如何在ggplot2中添加一个计算高于或低于某个值的点的图例?火山图

Posted

技术标签:

【中文标题】如何在ggplot2中添加一个计算高于或低于某个值的点的图例?火山图【英文标题】:How can I add a legend that counts points above or below a certain value in ggplot2? Volcano Plot 【发布时间】:2020-08-20 06:23:36 【问题描述】:

我正在尝试制作一个火山图(点图),其中某个 y 值以上的点根据它们的 x 值以从红色到绿色的渐变着色,并添加一个图例来指定点的数量高于这些值。

我有一个类似的代码:

set.seed(123)
x <- runif(600, -3, 3)
y <- runif(600, 0, 0.6)
df<- as.data.frame(cbind(x,y))

df %>% ggplot(aes(x, -log10(y), color=x)) +
  geom_point()+
  geom_hline(yintercept=1.3, color="darkgrey")+
  scale_fill_gradient(low="red",high="green", aesthetics = "color") 

哪个(用我的数据)产生了这个情节:

但我希望图例分别计算 y>1.3 & x>0 和 y>1.3 & x

有人可以帮我吗?

谢谢!!!!

【问题讨论】:

欢迎来到 SO。如果您使您的问题可重复minimal reproducible example,这将有所帮助。您能否将数据对象 BSvsBC_volcano 包含为最小的 data frametibble ?你可以使用dput(BSvsBC_volcano ) 【参考方案1】:

需要注意的一点:ggplot 中的图例仅用于解释美学的表现方式。为了让图例显示结果或数据(例如您的信息统计),您必须使用与 ggplot2 内置的方法不同的方法。

话虽如此,下面是一个使用钻石数据集子集的示例。

数据设置

请注意,我使用的是 diamonds 数据集的样本,因为我很懒,不想等待 50000+ 个数据点进行渲染。 :/

set.seed(12345)
di <- diamonds[sample(1:nrow(diamonds), 5000),]

我将设置绘图以表示 x 轴上的深度和 y 轴上的价格。我们将汇总高深度(> 平均深度)和低深度( 6000。稍后我们将使用此表。

di.summary <- as.data.frame(
    di %>% dplyr::filter(price > 6000) %>%
    group_by(depth > mean(di$depth)) %>% tally()
)
chartTable <- cbind(c('Low\nDepth', 'High\nDepth'), di.summary[,2])

基本绘图:Geom_point 颜色设置

这说明了可用于图表仅更改某些点颜色的方法。在这种情况下,我只希望价格高于 6000 的点被着色,而所有其他点都表示为灰点。最简单的方法是调用两个geom_point 并让它们使用不同的数据集。一个将应用颜色美学(在aes() 内),另一个将在aes() 函数外部指定灰色。

p <- ggplot(di, aes(depth, price)) +
    geom_point(data=di[which(di$price > 6000),], aes(color=depth), size=1) +
    geom_point(data=di[which(di$price <= 6000),], color='gray80', size=1) +
    geom_hline(yintercept=6000) +
    geom_vline(xintercept=mean(di$depth), linetype=2) +
    scale_color_gradient(high='red', low='green')
p

添加结果表

为了在您的绘图中显示表格,我们将不得不使用“grob”(我相信是“Graphics Object”的缩写)。我将使用gridExtra 库中的tableGrob 转换表格。然后将该 grob 对象传递给 annotation_custom(),并在图表中指定位置。

还有一点是我们计划将表格放在右下角在地块区域之外(图例下方)。为了做到这一点,我们需要通过在右侧添加一个绘图边距来为表格腾出空间。我们还需要关闭裁剪,以便注释可以在绘图区域之外表示。

library(gridExtra)

p +
  coord_cartesian(clip='off') +
  theme(
    plot.margin = margin(0,40,0,0)
  ) +
  annotation_custom(
    grob=tableGrob(chartTable, theme=ttheme_default(base_size = 9)),
    xmin=74.5, xmax=76, ymin=0, ymax=5000
  )

您可以对数据使用类似的方法。

使用文本注释的替代方法

使用tableGrob 的另一种方法是仅通过文本注释表示点数。我将在这里展示一个例子:

p +
    annotate(
        geom='label',
        x=min(di$depth), y=0.8*max(di$price),
        hjust=0,
        label=paste0('n=',di.summary[1,2])
    ) +
    annotate(
        geom='label',
        x=max(di$depth), y=0.8*max(di$price),
        hjust=1,
        label=paste0('n=',di.summary[2,2])
    )

虽然不是您的数据,但上述示例应为您提供足够的信息,以了解这些信息如何应用于您自己的数据。

【讨论】:

chemdork123 太棒了。感谢伟大的代码和解释!!!

以上是关于如何在ggplot2中添加一个计算高于或低于某个值的点的图例?火山图的主要内容,如果未能解决你的问题,请参考以下文章

如何获取行从高于或低于R中的临界值变化的次数的计数

为超过/低于阈值的值制作不同颜色的ggplot2热图

用python中的默认值替换高于和低于阈值的列表值?

Python时间序列 - 计算低于/高于和指定最短持续时间阈值的周期

如何删除列表中高于某个给定值的所有条目?

Python练习题 002:奖金计算