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

7
我的数据框如下所示:
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 => 如何在分面饼图上添加标签,但这些解决方案并没有帮到我。
5个回答

15

如何:

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)

在此输入图片描述

你可以考虑使用这个图表代替饼图,它看起来更加时尚,并且你现在对于饼图上的标签精度需求不高。


同意。但问题是这张图表来自我的毕业项目,当我提交项目论文时使用了饼图。现在我无法更改图表。 那时它运行得很好,我不知道代码出了什么问题。 无论如何,谢谢。 - Abdul Hakeem Mahmood
1
这句话的意思是“那个人要求制作饼图而不是花哨的图表”。 - confused

8
例如,我创建了一个包含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")

enter image description here


哎呀,我忘记了ggplo2,抱歉! - Worice

6

这里有一个与饼图中组的顺序和标签顺序匹配的想法。我按照value的降序对数据进行了排序。我也提前计算了百分比。在绘制ggplot图时,我使用fct_inorder()指定了mydfGroup的顺序(即Negative、Positive和Neutral)。当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"))

2

我同意@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()               

enter image description here


我认为你的图形中,积极和消极的百分比标签被颠倒了。 - jazzurro
1
谢谢@jazzurro,我已经纠正了。代码本来就没问题,只是原始数据框中的数字错了。如果OP提供了可重现的示例,我就不会犯那个错字了。 - Peter Ellis
它正在工作。谢谢@PeterEllis,你救了我的命 :) - Abdul Hakeem Mahmood

0

这是我的例子,仅使用基本的R代码。希望它有所帮助。

以鸢尾花数据为例
attach(iris)

检查鸢尾花物种比例。
a<- table(iris$Species)
class(a)  

然后将表格格式转换为矩阵,以便使用行名称代码。
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基础的基本饼图代码
pie(a_ratio,labels=rownames(a_mat))

通过使用paste()函数,进一步将比率值添加到标签中。
pie(a_ratio,labels=paste(rownames(a_mat),c("33%","33%","34%")))

最终饼图,请点击此链接


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接