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

How can I add a legend that counts points above or below a certain value in ggplot2? Volcano Plot

我正在尝试制作一个火山图(点图),其中高于某个 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<0 的点数(不显示颜色条)并且我想要线下方的点变黑。

有人可以帮我吗?

谢谢!!!!

有一点需要注意:ggplot中的图例只是为了解释美学是如何表现的。为了让图例显示结果或数据(例如您的信息统计),您必须使用不同于 ggplot2.

内置的方法

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

数据设置

请注意,我正在使用钻石数据集的示例,因为我很懒惰,不想等待 50000 多个数据点呈现。 :/

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

我将设置绘图以在 x 轴上表示深度,在 y 轴上表示价格。我们将汇总高深度(> 平均深度)和低深度(< 平均深度)且价格均大于 6000 的观察的数量。我们稍后将使用此 table。

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

添加结果table

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

还有一点,我们打算把table放在绘图区右下角外面(图例下方)。为此,我们需要通过在右侧添加绘图边距来为 table 腾出空间。我们还需要关闭裁剪,以便注释可以在绘图区域之外显示。

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])
    )

虽然不是你的数据,但上面的例子应该给你足够的信息来弄清楚这些如何应用于你自己的数据。