R语言进阶:从基础饼图到环形图与标签优化的实战指南

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()

这种图表需要注意颜色搭配,不同层级最好使用同一色系的不同饱和度,避免产生视觉混乱。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值