数据可视化——R语言ggplot2包绘制精美的小提琴图(并箱线图或误差条图组合)
概述:R语言使用ggplot2工具包绘制小提琴图。为了使数据表达更加丰富,同时将小提琴图与箱线图和误差条图相结合。另外,当每个组别有两个属性变量时,分半的小提琴图可节省绘图空间,同时更美观。为了突出小提琴图表达数据的优越性,常规的条形图结合误差条图也被绘制。
小提琴图(Violin Plot)用于显示数据分布及其概率密度,因其形状酷似小提琴而得名。
这种图表结合了箱线图和密度图的特征,主要用来显示数据的分布形状。中间的黑色粗条表示四分位数范围,从其延伸的幼细黑线代表95% 置信区间,而白点则为中位数。如果需要,中间的箱线图还可以替换为误差条图。
箱线图或误差条图在数据显示方面受到限制,简单的设计往往隐藏了有关数据分布的重要细节。例如使用箱线图时,我们不能了解数据分布是双模还是多模。小提琴图能够展示数据的真正分布范围和形状。值得注意的是,虽然小提琴图可以显示更多详情,但它们也可能包含较多干扰信息。
使用工具:R语言中的ggplot2工具包
本文的结构与之前一致,主要展示一些我在实践过程中的示例。以下示例依据内容分别介绍,完整的代码详见文章末尾。 数据采用模拟生成的数据。以下示例中的数据包括两个组别(group1和group2),每个组别共两个属性(Attribute_1和Attribute_1),每个组别的每个属性各100个测量值。
模拟数据的生成代码如下:
rm(list=ls()) #清除工作区
library(ggplot2)
#生成模拟数据
Group <- rep(c("group1","group2"),each=200) #组别变量
Group <- factor(Group) #组别因子化
Attribute <- c(rep("Attribute_1",100),rep("Attribute_2",100),rep("Attribute_1",100),rep("Attribute_2",100)) #每个组别的两个属性
Attribute <- factor(Attribute) #属性因子化
value <- c(rnorm(100)+1,rnorm(100)+2,rnorm(100)+1.2,rnorm(100)+1.5) #随机赋值
Data <- data.frame(Group=Group,Attribute=Attribute,value=value) #生成数据框
需要注意的时,绘制条形图和误差条图需要对原始数据进行适当的计算,如求均值,标准差,标准误和置信区间等。可以通过以下函数实现。以下函数来自:
http://www.cookbook-r.com/Manipulating_data/Summarizing_data/
需要确保已经安装好plyr包。如果没有安装,运行以下命令进行安装:install.packages(“plyr”)。plyr包用于数据整理很方便。
#对数据进行统计的函数
#指定分组变量和求值变量后,可计算出不同分组变量(或分组变量间的组合)对应的求值变量的均值,标准差,标准误,置信区间ci
#汇总数据
#计算出计数,平均值,标准差,均值的标准误差和置信区间(默认为95%)
#data:一个数据框
#measurevar:包含要汇总的变量的列的名称
#groupvars:包含分组变量的列名称的向量
#na.rm:一个布尔值,表示是否忽略NA
## conf.interval:置信区间的百分比范围(默认为95%)
## Summarizes data.
## Gives count, mean, standard deviation, standard error of the mean, and confidence interval (default 95%).
## data: a data frame.
## measurevar: the name of a column that contains the variable to be summariezed
## groupvars: a vector containing names of columns that contain grouping variables
## na.rm: a boolean that indicates whether to ignore NA's
## conf.interval: the percent range of the confidence interval (default is 95%)
summarySE <- function(data=NULL, measurevar, groupvars=NULL, na.rm=FALSE,
conf.interval=.95, .drop=TRUE) {
library(plyr)
# New version of length which can handle NA's: if na.rm==T, don't count them
length2 <- function (x, na.rm=FALSE) {
if (na.rm) sum(!is.na(x))
else length(x)
}
# This does the summary. For each group's data frame, return a vector with
# N, mean, and sd
datac <- ddply(data, groupvars, .drop=.drop,
.fun = function(xx, col) {
c(N = length2(xx[[col]], na.rm=na.rm),
mean = mean (xx[[col]], na.rm=na.rm),
sd = sd (xx[[col]], na.rm=na.rm)
)
},
measurevar
)
# Rename the "mean" column
datac <- rename(datac, c("mean" = measurevar))
datac$se <- datac$sd / sqrt(datac$N) # Calculate standard error of the mean
# Confidence interval multiplier for standard error
# Calculate t-statistic for confidence interval:
# e.g., if conf.interval is .95, use .975 (above/below), and use df=N-1
ciMult <- qt(conf.interval/2 + .5, datac$N-1)
datac$ci <- datac$se * ciMult
return(datac)
}
基于summarySE()函数依据数据中的不同组别变量之间的组合对变量value计算对应的计数,均值,标准差,标准误及置信区间。
代码如下:
#依据分组对vale进行统计
Data_summary <- summarySE(Data, measurevar="value", groupvars=c("Group","Attribute"))
执行结果如下:
Group Attribute N value sd se ci
1 group1 Attribute_1 100 1.035840 1.0497560 0.10497560 0.2082944
2 group1 Attribute_2 100 1.918411 0.9575014 0.09575014 0.1899890
3 group2 Attribute_1 100 1.073857 0.9276357 0.09276357 0.1840630
4 group2 Attribute_2 100 1.590875 0.9526457 0.09526457 0.1890256
其中,结果表示Group和Attribute的不同组合下对变量value进行计算,N表示计数,value表示value的均值,sd表示value的标准差,se表示value的标准误,ci可用于计算value的95%的置信区间,value的95%的置信区间为[value的均值-ci, value的均值+ci]。
先使用条形图结合误差条图表达数据,代码如下:
P1 <- ggplot(Data_summary,aes(x=Group, y=value, fill=Attribute)) + #“fill=”设置填充颜色依据Attribute指定
geom_point(aes(x=Group, y=value),pch=19,position=position_dodge(0.9),size=2.5)+ #绘制均值为点图
geom_bar(stat = "identity",position = "dodge",alpha = 0.7) + #绘制条形图
#如果误差条想表示标准差:请设置 ymin = value-sd, ymax=value+sd
#如果误差条想表示标准误:请设置 ymin = value-se, ymax=value+se
geom_errorbar(aes(ymin = value-ci, ymax=value+ci), #误差条表示95%的置信区间
width=0.1, #误差条末端短横线的宽度
position=position_dodge(0.9),
color="black",
alpha = 0.7,
size=0.5) +
scale_fill_manual(values = c("#56B4E9", "#E69F00"))+ #设置填充颜色
theme_bw()+ #背景变为白色
theme(axis.text.x=element_text(angle=15,hjust = 1,colour="black",family="Times",size=20), #设置x轴刻度标签的字体显示倾斜角度为15度,并向下调整1(hjust = 1),字体簇为Times大小为20
axis.text.y=element_text(family="Times",size=16,face="plain"), #设置y轴刻度标签的字体簇,字体大小,字体样式为plain
axis.title.y=element_text(family="Times",size = 20,face="plain"), #设置y轴标题的字体属性
panel.border = element_blank(),axis.line = element_line(colour = "black",size=1), #去除默认填充的灰色,并将x=0轴和y=0轴加粗显示(size=1)
legend.text=element_text(face="italic", family="Times", colour="black", #设置图例的子标题的字体属性
size=16),
legend.title=element_text(face="italic", family="Times", colour="black", #设置图例的总标题的字体属性
size=18),
panel.grid.major = element_blank(), #不显示网格线
panel.grid.minor = element_blank())+ #不显示网格线
ylab("Value")+xlab("") #设置x轴和y轴的标题
P1
jpeg(file = "results_Value_1.jpg",width =1600,height = 2000,units = "px",res =300) #结果保存
print(P1)
dev.off()
效果图如下:
小提琴图结合箱线图用于表达数据的代码如下:
P2<- ggplot(Data,