1. 基础饼图绘制:从R原生函数到ggplot2进阶
R语言中绘制饼图主要有两种方式:基础绘图系统的
pie()
函数和基于ggplot2的进阶方法。基础
pie()
函数确实简单易用,但存在明显的局限性——比如默认只有6种颜色循环使用、标签位置调整困难等问题。我刚开始用R做数据分析时也经常被这些问题困扰,后来发现自定义颜色是解决问题的第一步。
比如这个疾病统计数据的例子:
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")
colors <- c('#E5D2DD', '#53A85F', '#F1BB72', '#F3B1A0', '#D6E7A3',
'#57C3F3', '#476D87', '#E59CC4', '#AB3282', '#23452F', '#BD956A')
pie(ratio, labels=disease, col=colors, radius=1.0, clockwise=TRUE)
但ggplot2才是真正的生产力工具。虽然学习曲线陡峭,但一旦掌握就会发现其强大之处。用ggplot2绘制基础饼图需要理解一个核心概念:饼图本质上是堆叠条形图+极坐标系转换。这个认知转变对我后来的可视化工作帮助很大。
2. 环形图(空心饼图)制作技巧
环形图在学术报告中越来越常见,它比传统饼图多了中心空间可以用来展示摘要信息。用ggplot2配合ggforce包实现环形图其实非常简单——只需要调整
geom_arc_bar
中的半径参数
r0
。
我第一次尝试做环形图时犯了个典型错误:直接修改了原始饼图代码中的
r
参数,结果得到了一个非常小的饼图。后来才明白
r0
和
r
的关系:
-
r0:内半径,设为0就是实心饼图 -
r:外半径 两者差值决定了环形的宽度
library(ggplot2)
library(ggforce)
A <- data.frame(ratio, disease)
ggplot() +
geom_arc_bar(data=A, stat="pie",
aes(x0=0, y0=0, r0=1, r=2, amount=ratio, fill=disease)) +
scale_fill_manual(values=colors) +
theme_void()
环形图的中心空白区域大有可为。我常在那里添加总结性文字或关键指标,比如在这个疾病统计案例中,可以添加"Top3占比71.7%"这样的信息。用
annotate()
函数就能轻松实现:
last_plot() +
annotate("text", x=0, y=0, label="Top3占比71.7%",
size=6, fontface="bold")
3. 标签自动计算与防重叠策略
原始方法使用
annotate()
手动添加标签既繁琐又难以维护。我在实际项目中开发了一套自动化解决方案,主要依赖数据预处理和
geom_text_repel
的组合。
关键步骤是计算每个扇区的中心角度和标签位置。这里用到了一些三角函数知识:
library(dplyr)
library(ggrepel)
A_pies <- A %>%
mutate(end_angle = 2*pi*cumsum(ratio)/sum(ratio),
start_angle = lag(end_angle, default=0),
mid_angle = (start_angle + end_angle)/2,
hjust = ifelse(mid_angle>pi, 1, 0),
vjust = ifelse(mid_angle<pi/2 | mid_angle>3*pi/2, 0, 1))
ggplot(A_pies) +
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=1.1*sin(mid_angle), y=1.1*cos(mid_angle),
label=paste0(ratio,"%"), hjust=hjust, vjust=vjust),
size=3.5, show.legend=FALSE) +
scale_fill_manual(values=colors) +
coord_fixed() +
theme_void()
对于环形图,标签位置需要额外考虑半径因素。我的经验法则是将标签放在(r0+r)/2的位置,这样既不会太靠近中心,也不会太靠近外缘。
4. 高级应用:分割饼图与多层嵌套
分割饼图(Exploded pie chart)可以强调特定扇区。在ggforce中通过
explode
参数实现,这个参数接受一个数值向量,指定每个扇区的偏移量。注意偏移量不宜过大,否则会影响整体美观。
ggplot() +
geom_arc_bar(data=A, stat="pie",
aes(x0=0, y0=0, r0=0.5, r=1, amount=ratio,
fill=disease, explode=sample(c(0,0.1),11,TRUE)),
color="white") +
scale_fill_manual(values=colors)
多层嵌套饼图适合展示层级结构数据。实现的关键是使用多个
geom_arc_bar
层,每层使用不同的半径范围。我在分析销售数据时常用这种图表展示"大区-省份-城市"三级结构:
# 假设有两层数据
A1 <- data.frame(ratio=ratio[1:3], disease=disease[1:3], level="L1")
A2 <- data.frame(ratio=ratio[4:11], disease=disease[4:11], level="L2")
ggplot() +
geom_arc_bar(data=A1, aes(x0=0, y0=0, r0=0, r=0.7, amount=ratio, fill=disease)) +
geom_arc_bar(data=A2, aes(x0=0, y0=0, r0=0.7, r=1, amount=ratio, fill=disease)) +
scale_fill_manual(values=colors) +
theme_void()
这种图表需要注意颜色搭配,不同层级最好使用同一色系的不同饱和度,避免产生视觉混乱。

4446

被折叠的 条评论
为什么被折叠?



