使用ggplot2的coord_polar()绘制饼图异常,请求技术帮助
问题描述
有如下数据框,每行代表变量A-E,每列是观测值Obs1、Obs2,每个观测的变量值总和为1:
library(ggplot2) library(dplyr) test.df <- data.frame("Variable" = LETTERS[1:5], "Obs1" = c(0.1, 0, 0.5, 0.2, 0.2), "Obs2" = c(0.3, 0.7, 0, 0, 0))
数据框内容:
> test.df Variable Obs1 Obs2 1 A 0.1 0.3 2 B 0.0 0.7 3 C 0.5 0.0 4 D 0.2 0.0 5 E 0.2 0.0
需求是为每个观测生成饼图(共2个),要求:
- 图例显示所有变量且颜色统一
- 0值仅在图例显示,不在饼图中
但使用以下代码时,生成的饼图中五个变量占比均等,不符合Obs1的数值:
ggplot(test.df, aes(x='', y='Obs1', fill = Variable)) + geom_bar(width = 1, stat = 'identity') + coord_polar("y", start = 0)
解决步骤
1. 问题根源
代码里的y='Obs1'加了引号,会把Obs1当成字符串常量而非数据框的列名。ggplot会将每个变量的y值默认视为1,最终导致五个变量占比均等。
2. 正确实现方案
先将宽格式数据转为长格式,再通过分面生成两个饼图,同时强制保留所有变量的图例:
library(tidyr) # 转换为长格式数据 test_long <- test.df %>% pivot_longer(cols = starts_with("Obs"), names_to = "Observation", values_to = "Value") # 绘制符合要求的饼图 ggplot(test_long, aes(x = "", y = Value, fill = Variable)) + geom_bar(width = 1, stat = "identity") + coord_polar("y", start = 0) + facet_wrap(~ Observation) + # 按观测值分面生成两个饼图 scale_fill_discrete(drop = FALSE) + # 保留所有变量的图例(包括值为0的) theme_void() # 清理冗余的坐标轴和背景元素
关键说明
pivot_longer将宽格式数据转换为长格式,便于按观测值分组绘图scale_fill_discrete(drop=FALSE)确保所有变量(即使在某观测中值为0)都保留在图例中,且颜色统一- 值为0的变量不会在对应饼图中显示,但图例中仍会保留其颜色标识
内容的提问来源于stack exchange,提问作者twoHRdrive
相关产品推荐
相关产品推荐

