如何让viridis颜色条的上限超出原本的范围,以便在图例中最高的颜色更突出?

编程语言 2026-07-08

我正在绘制经 -log10转换的p 值。我的最感兴趣的点(0)变成了 Inf,在绘图时被视为NA。我手动用Viridis调色板的最高值来着色它们(na.value = "#fde725")。然而,这种黄色在图例中的可见度极低,几乎只是一丝,与背景的白色融为一体:

viridis colorscale has very little yellow

library(ggplot2)
library(patchwork)
dd <- cbind.data.frame(
  name=LETTERS[1:10],
  pval=c(0.01, 0.1, 1e-5, 1e-3, 0.4, 
         0, 1e-6, 0.1, 0, 1e-4)
)

p1 <- dd %>%
  ggplot( aes(y=name, x="x", fill=-log10(pval))) +
  geom_tile() +
  scale_fill_viridis_c(na.value = "#fde725", oob = scales::squish) +
  theme(aspect.ratio = 3) +
  labs(title="no limits", x=NULL, y=NULL)
p2 <- dd %>%
  ggplot( aes(y=name, x="x", fill=-log10(pval))) +
  geom_tile() +
  scale_fill_viridis_c(na.value = "#fde725", oob = scales::squish,
                       limits=c(0,7), breaks=seq(0:10)) +
  theme(aspect.ratio = 3) +
  labs(title="limits 0-7 + breaks 0-10", x=NULL, y=NULL)
p1+p2

我想让颜色条显示正常的Viridis颜色条,直到最高值为止,然后仅为图例的目的在视觉上把条延长几毫米,这样在尺度的顶部就能更清楚地看到NA/Inf/0的浓黄。

我已经尝试修改极限(只对把最高的有限值(G行)往下挪一个档有用)并在极限之外添加断点,但都对颜色尺度没有影响。

是否可以显示正常的viridis梯度颜色条,然后在它的一端再添加一个同色的“斑块”?

解决方案

好吧,我找到了答案。我差点就搞定了。

解决办法是把 limitsvalues 这两个参数结合使用。通过把上限 limit 设置为数据中最大(有限)值之外的某个值,并把 values 的上界设为介于该上限值与100% 之间的某个百分比,你就可以在颜色条的顶部/底部得到一个带有“边缘”颜色的区域。

colorbar combining limits + values parameters

在我的示例中,数据的最高有限值是6,上限是7。因此,6/7=0.85,使用 values=c(0, 0.9) 颜色在G 行“低于黄色”的区域,而条顶部的10% 区域是深黄,这样就不再只有一丝丝,而是出现明显的黄带。

p3 <- dd %>%
  ggplot( aes(y=name, x="x", fill=-log10(pval))) +
  geom_tile() +
  scale_fill_viridis_c(na.value = "#fde725", 
                       values=c(0,  0.9),
                       limits=c(0, 7)) +
  theme(aspect.ratio = 5) +
  labs(title="values 0, 0.9\nlimits 0-7", 
       x=NULL, y=NULL)
p4 <- dd %>%
  ggplot( aes(y=name, x="x", fill=-log10(pval))) +
  geom_tile() +
  scale_fill_viridis_c(na.value = "#fde725", 
                       values=c(0, 1.3/7,  0.9),
                       limits=c(0, 7)) +
  theme(aspect.ratio = 5) +
  labs(title="values 0, 0.19, 0.9\nlimits 0-7", 
       x=NULL, y=NULL)
p1+p2+p3+p4 +plot_layout(nrow=1)

最好的是 scale_fill_viridis() 基于 scales::pal_gradient_n(),因此该方案可以应用到多种颜色尺度。并且可以用来“拉伸”颜色尺度内的数值范围(第四列)。

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章