介绍

gghalves可以通过ggplot2轻松地编写自己想要的一半一半(half-half plots)的图片。比如:在散点旁边显示箱线图、在小提琴图旁边显示点图。
gghalves[1]_half_扩展添加到选定的geom。比如:geom_half_violin()函数,相当于geom_violin()函数的变体,该函数主要作用就是展示一半的小提琴图,然后与其他图形组合。还包含以下函数:
  • geom_half_boxplot
  • geom_half_violin
  • geom_half_point

安装

gghalves通过GitHub安装:
if
 (!require(devtools)) {

    install.packages(
'devtools'
)

}

devtools::install_github(
'erocoar/gghalves'
)

函数介绍

geom_half_violin(mapping = NULL, data = NULL, 
stat
 = 
"half_ydensity"
,

  position = 
"dodge"
, ..., side = 
"l"
, nudge = 0,

  draw_quantiles = NULL, trim = TRUE, scale = 
"area"
,

  na.rm = FALSE, show.legend = NA, inherit.aes = TRUE)

其参数包括:翻译来源生信玩家[2]
参数解释
mapping通过aes()指定图形属性映射。默认为NULL,使用ggplot()aes()指定的映射。
data指定数据框。默认为NULL,使用ggplot()中的数据。
stat覆盖geom_density()和stat_density()之间的默认连接。
position位置调整,可以是字符串,默认为"dodge",也可以是位置调整函数的调用结果。
side画半小提琴图的一侧。“ l”代表左,“ r”代表右,默认为“ l”。
nudge在小提琴图和分配给x轴上给定因子的空间中间之间添加空间。
draw_quantiles如果不是MULL(默认为NULL),在给定的密度估计分位数处绘制水平线。
trim若为TRUE(默认),将小提琴的尾部修整到数据范围。若为FALSE,不修剪尾巴。
scale如果为"area"(默认),则所有小提琴都具有相同的面积(修剪尾部之前)。
na.rm如果为FALSE(默认),则会使用警告删除缺失值。如果为TRUE,则会自动删除缺少的值。
show.legend逻辑值,默认为NA,若为FALSE,不显示该图层的图例; 若为TRUE,则显示该图层的图例。 它也可以是带有名称(图形属性)的逻辑向量,用来选择要显示的图形属性。如show.legend = c(size = TRUE,color = FALSE)表示显示size对应的图例,而不显示color对应的图例。
inherit.aes默认为TRUE,若为FALSE,覆盖ggplot()aes()默认属性,而不是与他们组合。
geom覆盖geom_density()stat_density()之间的默认连接。
bw要使用的平滑带宽度。如果是数字,则为平滑内核的标准差。
adjust多次带宽调整。这使得可以在仍使用带宽估计器的情况下调整带宽。例如,adjust = 1/2表示使用默认带宽的一半。

示例

单个函数

我们以iris数据集作为本例数据,先使用单个函数进行绘制。
if (!require(devtools)) {

install.packages('devtools')

}

devtools::install_github('erocoar/gghalves')

geom_half_boxplot

library(gghalves)


ggplot(iris, aes(x = Species, y = Petal.Width, fill = Species)) +

geom_half_boxplot()

默认为箱子在右,使用center = TRUE将箱子居中。下面函数参数调整类似,就不再绘制结果了,就把最原始的进行展示。
ggplot(iris, aes(x = Species, y = Petal.Width, fill = Species)) +

geom_half_boxplot(center = TRUE)

geom_half_violin

ggplot(iris, aes(x = Species, y = Petal.Width, fill = Species)) +

geom_half_violin()

geom_half_point

ggplot(iris, aes(x = Species, y = Petal.Width, fill = Species)) +

geom_half_point()

综合案例

云雨图

该案例来自官网案例,但并没有对代码进行解释。这里小编对代码进行详细解释,喜欢的伙伴,可以按照解释自己理解,并用到自己实际所需的复合图中。
先将数据的统计摘要进行计算存到了summ_iris中,包含了均值,标准差,数量标准误差。iris_plot为所需数据,这里将Species变量设置为因子,因为要用它作为分类变量。
library(tidyverse)

# 统计摘要

summ_iris <- iris %>%

group_by(Species) %>%

summarise(

mean = mean(Sepal.Length),

sd = sd(Sepal.Length),

n = n()

) %>%

mutate(se = sd/sqrt(n),

Species = factor(Species, levels = c('versicolor', 'setosa', 'virginica')))

summ_iris


## # A tibble: 3 x 5

## Species mean sd n se

## <fct> <dbl> <dbl> <int> <dbl>

## 1 setosa 5.01 0.352 50 0.0498

## 2 versicolor 5.94 0.516 50 0.0730

## 3 virginica 6.59 0.636 50 0.0899



# 数据转换

iris_plot <- iris %>%

mutate(Species = factor(Species, levels = c('versicolor', 'setosa', 'virginica')))

head(iris_plot)

接下来进行绘图,我们想要得到SpeciesSepal.Length的关系,其中Species为离散变量,Sepal.Length为连续变量。并绘制了半边的小提琴图,并将该图往右移了0.15,上下位置不变(position_nudge(x = .15, y = 0)),为了后面绘制其他图形留位置。
library(gghalves)

library(ggsignif)

library(ggsci)

library(ggpubr)

ggplot(iris_plot , aes(x = Species, y = Sepal.Length, fill = Species))+

geom_half_violin(aes(fill = Species),

position = position_nudge(x = .15, y = 0),

side = 'r')

接下来加入散点图,并使x坐标往左移动0.1(x = as.numeric(Species)-0.1),使用position_jitter使得重复的点分散开。
ggplot(iris_plot , aes(x = Species, y = Sepal.Length, fill = Species))+

geom_half_violin(aes(fill = Species),

position = position_nudge(x = .15, y = 0),

side = 'r') +

geom_point(aes(x = as.numeric(Species)-0.1,

y = Sepal.Length,color = Species),

position = position_jitter(width = .05),size = .25, shape = 20)

在原来基础上加入箱子图,位置放在正中间
ggplot(iris_plot , aes(x = Species, y = Sepal.Length, fill = Species))+

geom_half_violin(aes(fill = Species),

position = position_nudge(x = .15, y = 0),

adjust=1.5, trim=FALSE, colour=NA, side = 'r') +

geom_point(aes(x = as.numeric(Species)-0.1,

y = Sepal.Length,color = Species),

position = position_jitter(width = .05),size = .25, shape = 20) +

geom_boxplot(aes(x = Species,y = Sepal.Length, fill = Species),

outlier.shape = NA,

width = .05,

color = "black")

这里比较有趣的是,作者还通过geom_pointgeom_errorbar加入和汇总信息以及对应的误差项。
ggplot(iris_plot , aes(x = Species, y = Sepal.Length, fill = Species))+

geom_half_violin(aes(fill = Species),

position = position_nudge(x = .15, y = 0),

adjust=1.5, trim=FALSE, colour=NA, side = 'r') +

geom_point(aes(x = as.numeric(Species)-0.1,

y = Sepal.Length,color = Species),

position = position_jitter(width = .05),size = .25, shape = 20) +

geom_boxplot(aes(x = Species,y = Sepal.Length, fill = Species),

outlier.shape = NA,

width = .05,

color = "black")+

geom_point(data=summ_iris,

aes(x=Species,y = mean,group = Species, color = Species),

shape=18,

size = 1.5,

position = position_nudge(x = .1,y = 0)) +

geom_errorbar(data = summ_iris,

aes(x = Species, y = mean, group = Species, colour = Species,

ymin = mean-se, ymax = mean+se),

width=.05,

position=position_nudge(x = .1, y = 0)

)

使用ggsci包的scale_color_aaas(),scale_fill_aaas()将尺度的颜色进行改变(非常好用!)在下面展示另外一种配色(scale_color_jco
ggplot(iris_plot , aes(x = Species, y = Sepal.Length, fill = Species))+

geom_half_violin(aes(fill = Species),

position = position_nudge(x = .15, y = 0),

adjust=1.5, trim=FALSE, colour=NA, side = 'r') +

geom_point(aes(x = as.numeric(Species)-0.1,

y = Sepal.Length,color = Species),

position = position_jitter(width = .05),size = .25, shape = 20) +

geom_boxplot(aes(x = Species,y = Sepal.Length, fill = Species),

outlier.shape = NA,

width = .05,

color = "black")+

geom_point(data=summ_iris,

aes(x=Species,y = mean,group = Species, color = Species),

shape=18,

size = 1.5,

position = position_nudge(x = .1,y = 0)) +

geom_errorbar(data = summ_iris,

aes(x = Species, y = mean, group = Species, colour = Species,

ymin = mean-se, ymax = mean+se),

width=.05,

position=position_nudge(x = .1, y = 0)

) +

scale_color_aaas() +

scale_fill_aaas()

最后使用ggpubr包的geom_signif加入显著性结果,ggsave保存图片。
# 绘图

ggplot(iris_plot , aes(x = Species, y = Sepal.Length, fill = Species))+

geom_half_violin(aes(fill = Species),

position = position_nudge(x = .15, y = 0),

adjust=1.5, trim=FALSE, colour=NA, side = 'r') +

geom_point(aes(x = as.numeric(Species)-0.1,

y = Sepal.Length,color = Species),

position = position_jitter(width = .05),size = .25, shape = 20) +

geom_boxplot(aes(x = Species,y = Sepal.Length, fill = Species),

outlier.shape = NA,

width = .05,

color = "black")+

geom_point(data=summ_iris,

aes(x=Species,y = mean,group = Species, color = Species),

shape=18,

size = 1.5,

position = position_nudge(x = .1,y = 0)) +

geom_errorbar(data = summ_iris,

aes(x = Species, y = mean, group = Species, colour = Species,

ymin = mean-se, ymax = mean+se),

width=.05,

position=position_nudge(x = .1, y = 0)

) +

scale_color_jco() +

scale_fill_jco() +

geom_signif(comparisons = list(c("versicolor", "setosa"),

c("versicolor", "virginica"),

c("setosa", "virginica")),

y_position = c(8.2, 8.6, 8.4),

map_signif_level = c("***" = 0.001, "**" = 0.01, "*" = 0.05)) +

ggsave('云雨图.pdf', width = 6, height = 8)

混合图

最后是混合图,根据自己想要的图,可以自行添加。相信这个代码简单的图给大家学术作图上省了不少时间。
library(tidyverse)

ggplot() +

geom_half_boxplot(

data = iris %>% filter(Species=="setosa"),

aes(x = Species, y = Sepal.Length, fill = Species), outlier.color = NA) +

ggbeeswarm::geom_beeswarm(

data = iris %>% filter(Species=="setosa"),

aes(x = Species, y = Sepal.Length, fill = Species, color = Species), beeswarmArgs=list(side=+1)

) +

geom_half_violin(

data = iris %>% filter(Species=="versicolor"),

aes(x = Species, y = Sepal.Length, fill = Species), side="r") +

geom_half_dotplot(

data = iris %>% filter(Species=="versicolor"),

aes(x = Species, y = Sepal.Length, fill = Species), method="histodot", stackdir="down") +

geom_half_boxplot(

data = iris %>% filter(Species=="virginica"),

aes(x = Species, y = Sepal.Length, fill = Species), side = "r", errorbar.draw = TRUE,

outlier.color = NA) +

geom_half_point(

data = iris %>% filter(Species=="virginica"),

aes(x = Species, y = Sepal.Length, fill = Species, color = Species), side = "l") +

scale_fill_manual(values = c("setosa" = "#cba1d2", "versicolor"="#7067CF","virginica"="#B7C0EE")) +

scale_color_manual(values = c("setosa" = "#cba1d2", "versicolor"="#7067CF","virginica"="#B7C0EE")) +

theme(legend.position = "none") +

ggsave('综合图.pdf', width = 6, height = 8)

其他参考资料

  • Using gghalves--Frederik Tiedemann[3]
  • gghalves: Compose Half-Half Plots Using Your Favourite Geoms[4]
  • CRAN[5]

参考资料

[1]
gghalves: https://github.com/erocoar/gghalves
[2]
生信玩家: https://blog.csdn.net/weixin_43700050/article/details/107512448
[3]
Using gghalves--Frederik Tiedemann: https://erocoar.github.io/gghalves/
[4]
gghalves: Compose Half-Half Plots Using Your Favourite Geoms: https://cran.r-project.org/web/packages/gghalves/index.html
[5]
CRAN: https://rdrr.io/cran/gghalves/f/vignettes/gghalves.Rmd
继续阅读
阅读原文