不知道大家用ggplot2绘制饼图的时候有没有遇到过饼图上展示的顺序和图注上展示的顺序不一致的情况。今天小编就来跟大家一起来探讨一下这个问题。
首先我们来构建这样一个数据框,里面包含7种水果和相应的数目。
代码语言:javascript复制data=data.frame(name=c("apple","pear","orange","banana","grape","peach","cherry"),
num=c(10,5,9,3,7,5,8)
)
输出来是这样的
代码语言:javascript复制> data
name num
1 apple 10
2 pear 5
3 orange 9
4 banana 3
5 grape 7
6 peach 5
7 cherry 8
接下来我们用R里面的dplyr这个包来简单的处理一下数据,我们来算一下每种水果所占的百分比
代码语言:javascript复制library(dplyr)
data=data %>% mutate(prop=round(num/sum(num),2))
这时候数据就变成了
代码语言:javascript复制> data
name num prop
1 apple 10 0.21
2 pear 5 0.11
3 orange 9 0.19
4 banana 3 0.06
5 grape 7 0.15
6 peach 5 0.11
7 cherry 8 0.17
接下来用ggplot2来绘制饼图
代码语言:javascript复制library(ggplot2)
pie=ggplot(data, aes(x="", y=prop, fill=name))
geom_bar(stat="identity", width=1, color="white")
pie coord_polar("y", start=0) theme_void()
geom_text(aes(x=1.6,label = paste0(prop*100, "%")),
position = position_stack(vjust = 0.5))
geom_text(aes(label = num),
position = position_stack(vjust = 0.5))
scale_fill_discrete(name="fruite distribution",
labels=sprintf("%s %d",data$name, data$num))
ggtitle("fruite distribution")
theme(plot.title = element_text(hjust = 0.5))
你会得到这样一张图,图注上的顺序以及数字跟data里面的一致,但是饼图上的顺序和数字却不太对劲。
问题其实出在name的levels上,饼图默认会根据name的levels来按逆时针绘制。我们从堆积柱形图上可以发现,程序会默认按字母顺序来对name进行排序,这也是因子levels的默认排序方法。
所以这样得到的饼图的顺序实际上是apple,banana,cherry......而图注的顺序跟name本身的顺序一致为apple,pear,orange......
查看data$name你就会发现其中的玄机
代码语言:javascript复制> data$name
[1] apple pear orange banana grape peach cherry
Levels: apple banana cherry grape orange peach pear
那么针对这个问题,我们有两种解决方案
1. 修改name的levels,使其跟图注中的顺序一致
代码语言:javascript复制library(dplyr)
data=data.frame(name=c("apple","pear","orange","banana","grape","peach","cherry"),
num=c(10,5,9,3,7,5,8)
)
#重新构建一列叫type,指定levels跟name的顺序一致
data=data %>% mutate(prop=round(num/sum(num),2)) %>%
mutate(type=factor(name,levels=name))
library(ggplot2)
#画图的时候fill用type
pie=ggplot(data, aes(x="", y=prop, fill=type))
geom_bar(stat="identity", width=1, color="white")
pie coord_polar("y", start=0) theme_void()
geom_text(aes(x=1.6,label = paste0(prop*100, "%")),
position = position_stack(vjust = 0.5))
geom_text(aes(label = num),
position = position_stack(vjust = 0.5))
scale_fill_discrete(name="fruite distribution",
labels=sprintf("%s %d",data$name, data$num))
ggtitle("fruite distribution")
theme(plot.title = element_text(hjust = 0.5))
可以得到如下结果
2. 修改图注中的顺序,使其跟原来name的levels的顺序一致
代码语言:javascript复制library(dplyr)
data=data.frame(name=c("apple","pear","orange","banana","grape","peach","cherry"),
num=c(10,5,9,3,7,5,8)
)
data=data %>% mutate(prop=round(num/sum(num),2))
#获取name的levels的顺序
index=order(data$name)
library(ggplot2)
pie=ggplot(data, aes(x="", y=prop, fill=name))
geom_bar(stat="identity", width=1, color="white")
#标题居中
pie coord_polar("y", start=0) theme_void()
geom_text(aes(x=1.6,label = paste0(prop*100, "%")),
position = position_stack(vjust = 0.5))
geom_text(aes(label = num),
position = position_stack(vjust = 0.5))
scale_fill_discrete(name="fruite distribution",
labels=sprintf("%s %d",data$name[index], data$num[index])) #这里指定label的顺序
ggtitle("fruite distribution")
theme(plot.title = element_text(hjust = 0.5))
可以得到如下结果
按所占百分比排序之后再绘制饼图的代码如下