scale_fill_viridis色条未显示最小断点0.02的问题求助
ggplot2对数色条不显示指定最小值的问题解决
问题背景
我有一个名为sulfide的数据框,结构如下:
sulfide <- data.frame(SiteName = c("Site1", "Site1", "Site1", "Site1", "Site1", "Site1", "Site2", "Site2", "Site2", "Site2", "Site2", "Site2"), Activity = c("High", "High", "Medium", "Medium", "Low", "Low", "High", "High", "Medium", "Medium", "Low", "Low"), Depth = c("Shallow", "Deep", "Shallow", "Deep", "Shallow", "Deep", "Shallow", "Deep", "Shallow", "Deep", "Shallow", "Deep"), value = c(0.02, 0.02, 12.3, 8.6, 7.9, 9.7, 0.02, 0.02, NA, 8.6, 0.02, 1.0))
尝试绘制展示不同位点硫化物浓度及趋势的热力图,代码如下:
minimum <- 0.02 ggSulfide <- ggplot(sulfide, aes(x = Activity, y = Depth, fill = value)) + facet_grid(cols = vars(SiteName)) ggSulfide <- ggSulfide + geom_tile(color="white", size=0.1) + coord_equal() ggSulfide <- ggSulfide + scale_fill_viridis(name = "Concentration\n(mM)", trans = "log", breaks = c(minimum, 0.2, 2, 10), labels = c(minimum, 0.2, 2, 10), limits = c(minimum, max(sulfide$value, na.rm = TRUE)), na.value = "white") ggSulfide <- ggSulfide + geom_text(aes(label = value), size = geom.text.size) ggSulfide
尽管已指定breaks、labels和绘图limits,色条仍未显示需要的最小值0.02(这是检测限,不能调整)。但将minimum改为0.01时,色条会显示该最小值。请问原因是什么?如何修复原色条?
原因分析
问题出在对数转换色条的刻度渲染逻辑上:
- 当你把色条范围
limits的下限设为数据中的最小值0.02,同时使用log转换时,0.02是色条的边界点。ggplot2默认会自动隐藏和色条范围边界完全重合的断点,因为它默认边界是范围的起止,不需要额外标记。 - 当你把下限改成0.01时,0.02变成了色条范围内的一个普通点,而非边界,所以会被正常显示出来。
修复方法
方法1:强制显示边界刻度并取消自动扩展
在scale_fill_viridis中添加expand = c(0, 0)取消色条范围的自动扩展,同时通过guide_colorbar强制显示边界刻度:
minimum <- 0.02 ggSulfide <- ggplot(sulfide, aes(x = Activity, y = Depth, fill = value)) + facet_grid(cols = vars(SiteName)) + geom_tile(color="white", size=0.1) + coord_equal() + scale_fill_viridis( name = "Concentration\n(mM)", trans = "log", breaks = c(minimum, 0.2, 2, 10), labels = c(minimum, 0.2, 2, 10), limits = c(minimum, max(sulfide$value, na.rm = TRUE)), na.value = "white", expand = c(0, 0), # 取消色条范围的自动扩展 guide = guide_colorbar(show.limits = TRUE, ticks = TRUE) # 强制显示边界刻度 ) + geom_text(aes(label = value), size = 3) # 替换未定义的geom.text.size为具体数值 ggSulfide
方法2:使用自定义对数转换域
使用scales::log_trans()指定转换的定义域,避免边界断点被忽略:
minimum <- 0.02 ggSulfide <- ggplot(sulfide, aes(x = Activity, y = Depth, fill = value)) + facet_grid(cols = vars(SiteName)) + geom_tile(color="white", size=0.1) + coord_equal() + scale_fill_viridis( name = "Concentration\n(mM)", trans = scales::log_trans(domain = c(minimum, Inf)), breaks = c(minimum, 0.2, 2, 10), labels = c(minimum, 0.2, 2, 10), limits = c(minimum, max(sulfide$value, na.rm = TRUE)), na.value = "white", guide = guide_colorbar(show.limits = TRUE) ) + geom_text(aes(label = value), size = 3) ggSulfide
内容的提问来源于stack exchange,提问作者as1234
相关产品推荐
相关产品推荐

