在 R 中的饼图上添加百分比标签

Adding percentage labels on pie chart in R

我的数据框看起来像

df
   Group   value
1 Positive    52
2 Negative   239
3 Neutral     9

我想使用 ggplot 制作数据框的饼图。

pie <- ggplot(df, aes(x="", y=value, fill=Group)) +
       geom_bar(width = 1, stat = "identity") +
       coord_polar("y", start=0) 

这是我的饼图。

但是当我尝试在图表上添加百分比标签时

pie <- ggplot(df, aes(x="", y=value, fill=Group)) +
       geom_bar(width = 1, stat = "identity") +
       coord_polar("y", start=0) +
       geom_text(aes(y = value/2 + c(0, cumsum(value)[-length(value)]),
                 label = percent(value/300 )), size=5)

这是我的结果。

我已经看到许多与我相同的问题,即 R + ggplot2 => add labels on facet pie chart 并且解决方案没有帮助。

怎么样:

vals <- c(239, 52, 9)
val_names <- sprintf("%s (%s)", c("Negative", "Positive", "Neutral"), scales::percent(round(vals/sum(vals), 2)))
names(vals) <- val_names

waffle::waffle(vals) +
  ggthemes::scale_fill_tableau(name=NULL)

代替?

它 "fresher" 比饼图更好,而且您现在 have/want 在这些饼图标签上的精度水平并没有真正获得任何收益。

我同意@hrbrmstr 的观点,华夫饼图表会更好。但是要回答最初的问题......你的问题来自绘制楔形的顺序,默认为字母顺序。当您根据数据框中的顺序计算放置标签的位置时,结果是错误的。

作为可读性的一般原则,在实际代码绘制图形之前对标签和位置进行所有花哨的计算。

library(dplyr)
library(ggplot2)
library(ggmap) # for theme_nothing
df <- data.frame(value = c(52, 239, 9),
                 Group = c("Positive", "Negative", "Neutral")) %>%
   # factor levels need to be the opposite order of the cumulative sum of the values
   mutate(Group = factor(Group, levels = c("Neutral", "Negative", "Positive")),
          cumulative = cumsum(value),
          midpoint = cumulative - value / 2,
          label = paste0(Group, " ", round(value / sum(value) * 100, 1), "%"))

ggplot(df, aes(x = 1, weight = value, fill = Group)) +
   geom_bar(width = 1, position = "stack") +
   coord_polar(theta = "y") +
   geom_text(aes(x = 1.3, y = midpoint, label = label)) +
   theme_nothing()               

这是一个匹配饼图中组顺序和标签顺序的想法。我按 value 降序对数据进行排序。我也提前计算了百分比。当我绘制ggplot图时,我使用fct_inorder()mydf(即Negative,Positive和Neutral)中的顺序中指定了Group的顺序。当geom_label_repel()在饼图上添加标签时,标签的顺序与饼图的顺序相同。

library(dplyr)
library(ggplot2)
library(ggrepel)
library(forcats)
library(scales)

mydf %>%
arrange(desc(value)) %>%
mutate(prop = percent(value / sum(value))) -> mydf 

pie <- ggplot(mydf, aes(x = "", y = value, fill = fct_inorder(Group))) +
       geom_bar(width = 1, stat = "identity") +
       coord_polar("y", start = 0) +
       geom_label_repel(aes(label = prop), size=5, show.legend = F, nudge_x = 1) +
       guides(fill = guide_legend(title = "Group"))

数据

mydf <- structure(list(Group = structure(c(3L, 1L, 2L), .Label = c("Negative", 
"Neutral", "Positive"), class = "factor"), value = c(52L, 239L, 
9L)), .Names = c("Group", "value"), class = "data.frame", row.names = c("1", 
"2", "3"))

例如,我创建了一个包含 400 辆车的数据框 e3:

e3 <- data.frame(400)
e3 <- rep( c("car", "truck", "other", "bike", "suv"), c(60, 120, 20, 50, 150))

由于饼图对于比例特别有用,让我们看看我们的车辆的比例,然后我们将在这种情况下报告图表:

paste(prop.table(table(e3))*100, "%", sep = "")
[1] "15%"   "5%"    "30%"   "12.5%" "37.5%"

然后你就可以画饼图了,

pie(table(e3), labels = paste(round(prop.table(table(e3))*100), "%", sep = ""), 
col = heat.colors(5), main = "Vehicles proportions - n: 400")

这是我的示例,仅使用基本的 R 代码。希望对你有帮助。

以鸢尾花为例
attach(iris)
检查 iris$Species 的比例
a<- table(iris$Species)
class(a)  
然后将table格式转换成矩阵,以便使用rowname代码
a_mat<- as.matrix(a)
a_mat
计算每个物种的比例
a_ratio<- a_mat[,1]/sum(a_mat[,1])*100
a_ratio
由于每个物种占 0.33333(即 33.33333%),我只需要使用 signif() 保留 2 位小数
a_ratio<- signif(a_ratio,3)
a_ratio
R base的基本饼图代码
pie(a_ratio,labels=rownames(a_mat))
使用 paste() 进一步向标签添加比率值
pie(a_ratio,labels=paste(rownames(a_mat),c("33%","33%","34%")))

final pie chart, please click this link