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

2020-08-06 14:07:31 浏览数 (2)

不知道大家用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))

可以得到如下结果

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

0 人点赞