R语言绘制好看的饼图、空心饼图
2022-03-21 本文已影响0人
KS科研分享与服务
饼图或者说扇形图在统计分析结果展示中非常常用,R语言自带做饼图的函数pie,做起来非常简单,只需提供比例,样品名称即可。
#构建数据
ratio <- c(24.2, 21.9, 7.6, 5.2,4.3,3.2,2.6,2.6,1.8,1.8,24.8)
disease <- c("Heart disease", "Cancer","injuries", "CPD",
"Stroke",'Type2 diabetes',"AD","Suicide",
"IP","Chronic liver disease","Other")
pie(ratio, labels=disease,
radius = 1.0,clockwise=T,
main = "Male individuals")
图片
默认的颜色只有6中,循环使用的,不过这个颜色可以自定义。
#自定义颜色
colors <-c('#E5D2DD', '#53A85F', '#F1BB72', '#F3B1A0',
'#D6E7A3', '#57C3F3', '#476D87',
'#E59CC4', '#AB3282', '#23452F', '#BD956A')
pie(ratio, labels=disease,
radius = 1.0,clockwise=T,
col = colors,
main = "Male individuals")
图片
用pie作图其实就够了,但奈何很“卷”,有其他好看的饼图,所以接下来还是结合ggplot2与ggforce做可以变换的饼图,例如空心饼图。单独用ggplot2作图比较繁琐,不建议去尝试了,太费时间没必要。
先做一个基本的饼图。
A <- data.frame(ratio, disease)#构建一个数据框
library(ggplot2)
library(ggforce)
ggplot()+
theme(panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
axis.ticks = element_blank(),
axis.text.y = element_blank(),
axis.text.x = element_blank(),
legend.title=element_blank(),
panel.border = element_blank(),
panel.background = element_blank())+#去除没用的ggplot背景,坐标轴
xlab("")+ylab('')+#添加颜色
scale_fill_manual(values = c('#E5D2DD', '#53A85F', '#F1BB72', '#F3B1A0',
'#D6E7A3', '#57C3F3', '#476D87',
'#E59CC4', '#AB3282', '#23452F', '#BD956A'))+
geom_arc_bar(data=A,
stat = "pie",
aes(x0=0,y0=0,r0=0,r=2,
amount=ratio,fill=disease)
)+#饼图
annotate("text",x=1.6,y=1.5,label="24.20%",angle=-50)+
annotate("text",x=1.6,y=-1.5,label="21.9%",angle=45)+
annotate("text",x=0,y=-2.2,label="7.6%",angle=0)+
annotate("text",x=-0.8,y=-2,label="5.2%",angle=-20)+
annotate("text",x=-1.3,y=-1.7,label="4.3%",angle=-40)+
annotate("text",x=-1.6,y=1.5,label="24.8%",angle=45)#手动注释,还是很麻烦
图片
要想得到空心饼图,只需要将geom_arc_bar参数中r0改为1即可。
geom_arc_bar(data=A,
stat = "pie",
aes(x0=0,y0=0,r0=1,r=2,
amount=ratio,fill=disease))
图片
想要分割饼图,geom_arc_bar中添加explode参数。
geom_arc_bar(data=A,
stat = "pie",
aes(x0=0,y0=0,r0=1,r=2,
amount=ratio,fill=disease,
explode=c(0.05,0.1,0.05,0.05,
0.05,0.05,0.05,0.05,0.05,0.1,0.1))
)
图片
可以发现,以上作图有一个bug就是添加比例标记很麻烦,要想实现自动化需要编写函数很麻烦。参考:https://stackoverflow.com/questions/52960015/how-to-avoid-label-overlap-in-pie-chart。可以先将每个标签角度计算好,再添加,结果还好。
ratio <- c(24.2, 21.9, 7.6, 5.2,4.3,3.2,2.6,2.6,1.8,1.8,24.8)
disease <- c("Heart disease", "Cancer","injuries", "CPD",
"Stroke",'Type2 diabetes',"AD","Suicide",
"IP","Chronic liver disease","Other")
Group <- c("male","male","male","male","male","male",
"male","male","male","male","male")
A <- data.frame(Group, disease,ratio)
#添加角度
A_pies4 <- left_join(A,
A %>%
group_by(Group) %>%
summarize(Cnt_total = sum(ratio))) %>%
group_by(Group) %>%
mutate(end_angle = 2*pi*cumsum(ratio)/Cnt_total,
start_angle = lag(end_angle, default = 0),
mid_angle = 0.5*(start_angle + end_angle))
#添加位置
rlabel = 0.6
A_pies4 <- mutate(A_pies4,
hjust = ifelse(mid_angle>pi, 1, 0),
vjust = ifelse(mid_angle<pi/2 | mid_angle>3*pi/2, 0, 1))
rlabel = 1.05
#作图很前面一样,环形做法亦是如此
ggplot(A_pies4) +
geom_arc_bar(aes(x0 = 0, y0 = 0, r0 = 0, r = 1,
start = start_angle, end = end_angle, fill = disease))+
geom_text_repel(aes(x = rlabel*sin(mid_angle),
y = rlabel*cos(mid_angle),
label = paste0 (round(ratio), "%"),
hjust = hjust, vjust = vjust),nudge_x = .1,
segment.size = 0.5,
show.legend = FALSE) +
coord_fixed() +
scale_fill_manual(values = c('#E5D2DD', '#53A85F', '#F1BB72', '#F3B1A0',
'#D6E7A3', '#57C3F3', '#476D87',
'#E59CC4', '#AB3282', '#23452F', '#BD956A'))+
scale_x_continuous(limits = c(-1.2, 1.2), name = "", breaks = NULL, labels = NULL) +
scale_y_continuous(limits = c(-1.2, 1.2), name = "", breaks = NULL, labels = NULL) +
theme_void()+
theme(plot.title = element_text(size = 14, hjust = 0.5))+
labs(title = "Male individuals")
图片
好了以上就是饼图的内容了,其本质是为了统计比例,结果解读比较直观,我们也是跟风做了一些变换的图形,其实最简单的饼图就可以了,各取所需。此外,还有很多其他方法制作饼图,感兴趣的自行百度了解。