创建具有成对点和正确方向的分割小提琴图
Posted
技术标签:
【中文标题】创建具有成对点和正确方向的分割小提琴图【英文标题】:Create a split violin plot with paired points and proper orientation 【发布时间】:2022-01-20 15:07:20 【问题描述】:使用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
参数,它采用一个数字向量来指定要翻转的几何图形。
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 似乎没有解决这个问题。
问题
-
如何创建带有成对点的
geom_violindot()
图,从而使连接它们的点和线“夹在”小提琴两半之间?我怀疑有一个使用David Robinson's GeomFlatViolin
function 的解决方案,虽然我还没有弄清楚。
在最后一个图中,请注意线条相对于它们连接的点是倾斜的。应该为position_dots
和position
参数提供什么位置调整函数以使点和线正确对齐?
【问题讨论】:
虽然这不是您想听到的答案,但这可能是值得考虑的事情。不要追求这种可视化的想法。它令人困惑,令人费解,而且故事没有得到很好的体现。您尝试将成对的观察结果和数据的估计分布结合起来。还有其他选择。在您的示例中:在散点图中显示配对数据(每个物种在其自己的连续轴上),对于估计的分布显示例如 iso 等高线(例如 stat_density_2d) @tjebo 感谢您的评论,我可以理解可能有更好的方法来表示此类数据。如果您想写一个答案来解释您的方法作为框架挑战,我可能会在没有其他答案的情况下接受它 @acvill:可视化的目标是什么? @tjebo 我有数百个特定类型的短基因组特征。我有两种治疗的这些特征的转录组学数据。我想显示治疗之间每个特征的 RPKM 的相对变化。我还想表明,这种特征类型的治疗之间的平均 RPKM 通常会发生变化。我知道这个案例的经典可视化是火山图,但我想显示 RPKM 而不是倍数变化/p 值。 【参考方案1】:不确定是否将 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 值,而不是点所在的位置在行中。
【讨论】:
这解决了我的主要问题,谢谢。我希望“延长点线”的过程也可以应用于连接线,但似乎并不那么容易。【参考方案2】:根据评论 - 这不是您问题的直接答案,但我相信您在使用“斜率图”光学元件时可能无法获得最令人信服的可视化效果。这会很快变得令人费解(很多点/线重叠)并且消息会丢失。
要显示成对观察之间的变化(治疗 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 日创建
【讨论】:
感谢您的选择——在二维中映射单个点肯定比在一个维度中映射两个链接点更干净。感谢seq_along()
的提示!以上是关于创建具有成对点和正确方向的分割小提琴图的主要内容,如果未能解决你的问题,请参考以下文章