【问题标题】:How can I keep ggplot2 annotations aligned and in fixed position on plot?如何保持 ggplot2 注释对齐并在绘图上的固定位置?
【发布时间】:2021-08-03 09:47:39
【问题描述】:

我正在绘制 2 个密度并尝试添加一些注释,这些注释在文本旋转 90 度时水平对齐,但当注释的字符长度不同时,我似乎无法让它们对齐。

library(ggplot2)

n <- 10000 
mu_a <- .089
mu_b <- .099
s_a <- .0092
s_b <- .004

df <- data.frame(
  variant = factor(c(rep("A", n),rep("B", n))),
  p = c(rnorm(n = n, mean = mu_a, sd = s_a), rnorm(n = n, mean = mu_b, sd = s_b)))


ggplot(df, aes(x = p, fill = variant)) +
  geom_density() +
  scale_x_continuous(labels = scales::percent) +
  scale_y_continuous(expand = expansion(mult = c(0, .1))) +
  annotate("text",
      x = c(mu_a,mu_b), 
      y = Inf,
     vjust = "center",
     hjust = 6, 
     label = c("5char","06char"),
     angle = 90
     )

reprex package (v0.3.0) 于 2021-05-12 创建

https://i.imgur.com/CxW1pjP.png处绘制图像

我尝试使用 scale_y_continuous(y = ..scaled..) 将 y 轴更改为 0:1 比例,然后将注释 y 值设置为固定位置,例如 y = 0.2,但密度大小不合适。尝试了各种 hjust 和 vjust 的组合。我认为这些应该像情节的百分比一样起作用。所以vjust = 0.2 意味着情节增加了 20%,但对我来说并不是这样。我没想到通过将文本旋转 90 度,hjust 和 vjust 会交换,但这似乎是发生的事情。

【问题讨论】:

  • 使用stackoverflow.com/questions/7705345/… 找到的灵感,我尝试从图中获取 y 比例限制,并设置相对于该值的注释 y 值。因此,如果绘图对象是g,这将获取比例上限label_y &lt;- ggplot_build(g)$layout$panel_scales_y[[1]]$range$range[[2]] * 0.2。似乎可以始终将标签放置在绘图高度的 20% 处。构建绘图后添加注释之外的更好方法?

标签: r ggplot2 density-plot


【解决方案1】:

我在这里找到的最佳答案是:

  1. annotation_custom() 与网格包和textGrob() 函数一起使用。这确实允许按 x 和 y 轴的百分比定位注释。问题是你不能像我试图做的那样混合设置 x 指向比例和 y 到比例的方法。
  2. 计算图中值范围的上限。你可以从像ggplot_build(.)$layout$panel_scales_y[[1]]$range$range[[2]]这样的ggplot对象中得到它,或者你可以从像d &lt;- density(.)然后d$y[which.max(d$y)]这样的密度函数中得到它。获得范围的上限后,您可以继续使用该上限的一部分作为 y 位置来构建绘图。

将 y 比例设置为 ..scaled.. 确实将 y 比例设置为最大 1,但是,在绘制多个密度时,它将两者设置为它们自己的比例,而不是精确地相互缩放。如此宽和窄的密度将具有相同的高度。

【讨论】:

    【解决方案2】:

    我不确定我是否 100% 关注,但试试这个:

    ggplot(df, aes(x = p, ..scaled.., fill = variant)) +
      geom_density(alpha = 0.8, adjust = 0.2) +
      scale_x_continuous(labels = scales::percent) +
      scale_y_continuous(expand = expansion(mult = c(0, .1))) +
      annotate("text",
               x = c(mu_a,mu_b), 
               y = 0.5,
               hjust = 0.5, 
               label = c("5char","20charxxxxxxxxxxxxxx"),
               angle = 90
      )
    

    主要标注:

    • y 设置为 0.5。这是一个密度图,因此可以在映射中使用..scaled.. 对其进行缩放以使最大y 始终为1(请参阅geom_density y-axis goes above 1

    • 删除了vjust

    • hjust 更改为 0.5。虽然接受大于 1 的值,但最简单的做法是将 0 视为左对齐,1 视为右对齐,0 视为居中对齐。它是hjust 而不是vjust 的原因是因为理由是从文本的角度而不是情节的方向(这是有道理的——考虑一个不是 0 或 90 的角度)。

    • 我将alpha 值放入`geom_density() 函数中,以便显示两者的完整曲线(这根本不是问题的一部分,但我忍不住)

    这应该返回以下内容:

    Plot using the code above

    【讨论】:

    • 这是其余部分所依赖的第一个标注,对吧?如果我更改s_a &lt;- .00092s_b &lt;- .0004,则最大值变为1000。这也不是我对密度图的期望,而是obv。我在这里不明白的东西。
    猜你喜欢
    • 2012-04-07
    • 1970-01-01
    • 2020-07-20
    • 1970-01-01
    • 2014-12-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-24
    相关资源
    最近更新 更多