创建具有配对点和正确方向的分割小提琴图

Create a split violin plot with paired points and proper orientation

使用 ggplot2,我可以创建一个带有重叠点的小提琴图,并且可以使用 geom_line() 连接成对的点。

library(datasets)
library(ggplot2)
library(dplyr)

iris_edit <- iris %>% group_by(Species) %>%
  mutate(paired = seq(1:length(Species))) %>%
  filter(Species %in% c("setosa","versicolor"))

ggplot(data = iris_edit,
       mapping = aes(x = Species, y = Sepal.Length, fill = Species)) +
  geom_violin() +
  geom_line(mapping = aes(group = paired),
            position = position_dodge(0.1),
            alpha = 0.3) +
  geom_point(mapping = aes(fill = Species, group = paired),
             size = 1.5, shape = 21,
             position = position_dodge(0.1)) +
  theme_classic() +
  theme(legend.position = "none",
        axis.text.x = element_text(size = 15),
        axis.title.y = element_text(size = 15),
        axis.title.x = element_blank(),
        axis.text.y = element_text(size = 10))

see 程序包包含 geom_violindot() 函数,用于在其组成点旁边绘制减半的小提琴图。我发现此功能在绘制大量点时很有用,这样小提琴就不会被遮挡。

library(see)

ggplot(data = iris_edit,
       mapping = aes(x = Species, y = Sepal.Length, fill = Species)) +
  geom_violindot(dots_size = 0.8,
                 position_dots = position_dodge(0.1)) +
  theme_classic() +
  theme(legend.position = "none",
        axis.text.x = element_text(size = 15),
        axis.title.y = element_text(size = 15),
        axis.title.x = element_blank(),
        axis.text.y = element_text(size = 10))

现在,我想将 geom_line() 添加到 geom_violindot() 以连接成对的点,如第一张图片所示。理想情况下,我希望点在里面,小提琴在外面,这样线条就不会与小提琴相交。 geom_violindot() 包含 flip 参数,该参数采用指定要翻转的 geom 的数值向量。

ggplot(data = iris_edit,
       mapping = aes(x = Species, y = Sepal.Length, fill = Species)) +
  geom_violindot(dots_size = 0.8,
                 position_dots = position_dodge(0.1),
                 flip = c(1)) +
  geom_line(mapping = aes(group = paired),
            alpha = 0.3,
            position = position_dodge(0.1)) +
  theme_classic() +
  theme(legend.position = "none",
        axis.text.x = element_text(size = 15),
        axis.title.y = element_text(size = 15),
        axis.title.x = element_blank(),
        axis.text.y = element_text(size = 10))

如您所见,调用 flip 会反转小提琴的一半,但不会反转相应的点。 see documentation 似乎没有解决这个问题。

问题

  1. 如何创建带有成对点的 geom_violindot() 图,使点和连接它们的线“夹在”小提琴两半之间?我怀疑有一个使用 的解决方案,但我还没弄明白。
  2. 在最后一张图中,请注意线条相对于它们连接的点是歪斜的。应该向 position_dotsposition 参数提供什么位置调整函数,以便点和线正确对齐?

不确定如何将 geom_violindot 与 see 包一起使用。但是您可以将 geom_half_violon 和 geom_half_dotplot 的组合与 gghalves 包一起使用,并对数据进行子集化以指定方向:

library(gghalves)

 ggplot(data = iris_edit[iris_edit$Species == "setosa",],
           mapping = aes(x = Species, y = Sepal.Length, fill = Species)) +
   geom_half_violin(side = "l") +
    geom_half_dotplot(stackdir = "up") +
    geom_half_violin(data = iris_edit[iris_edit$Species == "versicolor",],
                     aes(x = Species, y = Sepal.Length, fill = Species), side = "r")+
    geom_half_dotplot(data = iris_edit[iris_edit$Species == "versicolor",],
                      aes(x = Species, y = Sepal.Length, fill = Species),stackdir = "down") +
    geom_line(data = iris_edit, mapping = aes(group = paired),
              alpha = 0.3)

请注意,配对中的线不会正确对齐,因为点图对每个观察值进行分箱,然后拉长点线——配对线仅对应于 aes 中定义的 x 值,而不对应于点在行中。

根据评论 - 这不是您问题的直接答案,但我相信您在使用“斜率图”光学器件时可能无法获得最令人信服的可视化效果。这很快变得令人费解(很多点/线重叠)并且消息丢失了。

要显示成对观察(处理 1 与处理 2)之间的变化,您还可以(我认为:更好)使用散点图。您可以显示每个观察结果,变化会立即变得清晰。为了更直观,可以加一行等号。

我认为你不需要显示估计分布(左图),但如果你想显示这个,你可以使用二维密度估计,geom_density2d(右图)情节)

library(tidyverse)
## patchwork only for demo purpose
library(patchwork)

iris_edit <- iris %>% group_by(Species) %>%
  ## use seq_along instead
  mutate(paired = seq_along(Species)) %>%
  filter(Species %in% c("setosa","versicolor")) %>%
## some more modificiations
  select(paired, Species, Sepal.Length) %>%
  pivot_wider(names_from = Species, values_from = Sepal.Length)

lims <- c(0, 10)

p1 <- 
  ggplot(data = iris_edit, aes(setosa, versicolor)) +
  geom_abline(intercept = 0, slope = 1, lty = 2) +
  geom_point(alpha = .7, stroke = 0, size = 2) +
  cowplot::theme_minimal_grid() +
  coord_equal(xlim = lims, ylim = lims) +
  labs(x = "Treatment 1", y = "Treatment 2")

p2 <- 
  ggplot(data = iris_edit, aes(setosa, versicolor)) +
  geom_abline(intercept = 0, slope = 1, lty = 2) +
  geom_density2d(color = "Grey") +
  geom_point(alpha = .7, stroke = 0, size = 2) +
  cowplot::theme_minimal_grid() +
  coord_equal(xlim = lims, ylim = lims) +
  labs(x = "Treatment 1", y = "Treatment 2")

p1+ p2

reprex package (v2.0.1)

于 2021-12-18 创建