【问题标题】:violin_plot() with continuous axis for grouping variable?violin_plot() 具有用于分组变量的连续轴?
【发布时间】:2020-06-11 10:47:22
【问题描述】:

由于显而易见的原因,用于在 ggplot2 中创建 geom_violin() 图的分组变量预计是离散的。但是我的离散值是数字,我想以连续的比例显示它们,以便我可以将这些数字的连续函数叠加在小提琴上。玩具示例:

library(tidyverse)
df <- tibble(x = sample(c(1,2,5), size = 1000, replace = T),
             y = rnorm(1000, mean = x))
ggplot(df) + geom_violin(aes(x=factor(x), y=y))

这就像您想象的那样工作:x 轴值(等距)标记为 1、2 和 5 的小提琴,它们的均值分别位于 y=1、2、5。我想通过手段覆盖一个连续的函数,例如 y=x。那可能吗?添加+ scale_x_continuous() 可以预测得到Error: Discrete value supplied to continuous scale。一个解决方案可能会通过数字 x 值水平传播小提琴,即 2 和 5 之间的间距是 1 和 2 之间的三倍,但这不是我想要实现的唯一事情 -覆盖连续函数是关键问题。 如果这是不可能的,欢迎替代可视化建议。我知道我可以用一个简单的散点图代替小提琴,以粗略地了解给定 x 的密度作为 y 的函数。

【问题讨论】:

    标签: r ggplot2


    【解决方案1】:

    试试这个。正如您已经猜到的那样,通过数值传播小提琴是解决方案的关键。为此,我扩展 df 以包含区间 min(x)max(x) 中的所有 x 值,并使用 scale_x_discrete(drop = FALSE) 以便显示所有值。

    注意:感谢@ChrisW 提供了我的方法的更通用示例。

    library(tidyverse)
    
    set.seed(42) 
    
    df <- tibble(x = sample(c(1,2,5), size = 1000, replace = T), y = rnorm(1000, mean = x^2))
    # y = x^2  
    # add missing x values 
    x.range <- seq(from=min(df$x), to=max(df$x)) 
    df <- df %>% right_join(tibble(x = x.range))
    #> Joining, by = "x"
    # Whatever the desired continuous function is: 
    df.fit <- tibble(x = x.range, y=x^2) %>% 
      mutate(x = factor(x))
    
    ggplot() + 
      geom_violin(data=df, aes(x = factor(x, levels = 1:5), y=y)) + 
      geom_line(data=df.fit, aes(x, y, group=1), color = "red") + 
      scale_x_discrete(drop = FALSE)
    #> Warning: Removed 2 rows containing non-finite values (stat_ydensity).
    

    reprex package (v0.3.0) 于 2020-06-11 创建

    【讨论】:

    • 完美,谢谢!供其他人参考,上面的df_mean 被任意理论拟合代替,而不是直接来自数据的示例:
    • library(tidyverse) set.seed(42) df &lt;- tibble(x = sample(c(1,2,5), size = 1000, replace = T), y = rnorm(1000, mean = x^2)) # y = x^2 # add missing x values x.range &lt;- seq(from=min(df$x), to=max(df$x)) df &lt;- df %&gt;% right_join(tibble(x = x.range)) # Whatever the desired continuous function is: df.fit &lt;- tibble(x = x.range, y=x^2) %&gt;% mutate(x = factor(x)) ggplot() + geom_violin(data=df, aes(x = factor(x, levels = 1:5), y=y)) + geom_line(data=df.fit, aes(x, y, group=1), color = "red") + scale_x_discrete(drop = FALSE)
    • 嗯@stefan 也许您可以将其编辑到您的答案中,使其格式正确?
    • 嗨@ChrisW。好想法。我用你的一般例子代替了我的例子。下一次:随意自己进行编辑。 (;
    【解决方案2】:

    ggplot 直接内置了以连续比例绘制小提琴图的功能。

    关键是保留原始连续变量(而不是将其转换为因子变量)并指定如何在geom_violin() 对象的美学映射中对其进行分组。可以使用cut_width 参数修改组的宽度,具体取决于手头的数据。

    library(tidyverse)
    
    df <- tibble(x = sample(c(1,2,5), size = 1000, replace = T),
                 y = rnorm(1000, mean = x))
    
    ggplot(df, aes(x=x, y=y)) +
      geom_violin(aes(group = cut_width(x, 1)), scale = "width") +
      geom_smooth(method = 'lm')
    

    通过使用这种方法,所有连续数据的几何图形及其不同的功能都可以与小提琴图相结合,例如我们可以很容易地用黄土曲线替换这条线并添加点的散点图。

    ggplot(df, aes(x=x, y=y)) +
      geom_violin(aes(group = cut_width(x, 1)), scale = "width") +
      geom_smooth(method = 'loess') +
      geom_point()
    

    更多示例可以在ggplotviolin plots 的帮助文件中找到。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-12-29
      • 1970-01-01
      • 1970-01-01
      • 2013-08-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多