ggplot2饼图和图注顺序不一致如何解决

时间:2022-07-22
本文章向大家介绍ggplot2饼图和图注顺序不一致如何解决,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

不知道大家用ggplot2绘制饼图的时候有没有遇到过饼图上展示的顺序和图注上展示的顺序不一致的情况。今天小编就来跟大家一起来探讨一下这个问题。

首先我们来构建这样一个数据框,里面包含7种水果和相应的数目。

data=data.frame(name=c("apple","pear","orange","banana","grape","peach","cherry"),
                num=c(10,5,9,3,7,5,8)
                )

输出来是这样的

> 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这个包来简单的处理一下数据,我们来算一下每种水果所占的百分比

library(dplyr)
data=data %>% mutate(prop=round(num/sum(num),2))

这时候数据就变成了

> 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来绘制饼图

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你就会发现其中的玄机

> data$name
[1] apple  pear   orange banana grape  peach  cherry
Levels: apple banana cherry grape orange peach pear

那么针对这个问题,我们有两种解决方案

1. 修改name的levels,使其跟图注中的顺序一致

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的顺序一致

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

可以得到如下结果

按所占百分比排序之后再绘制饼图的代码如下