饼图ggplot:文本方向和图形不同

时间:2018-10-28 08:56:44

标签: r ggplot2

我有一个像这样的数据集

data=data.frame(Var1 = c('a', 'b'), Freq=c(31, 48))

我想制作一个ggplot饼图。我这样做如下

library(ggplot2)
tbl <- transform(data,
                 freq = cumsum(Freq),
                 perc = Freq/sum(Freq),
                 pos = (cumsum(Freq) - 0.5 * Freq) / sum(Freq))
ggplot(data=tbl, aes(x="", y=perc, fill = factor(Var1))) + 
  geom_bar(width = 0.8, stat="identity") + 
  coord_polar(theta="y",start = 0,  direction = 1) +
  geom_text(aes(label=paste(round(perc*100),"%",sep=""), y=pos), 
            color="grey20" ,size=15) +
  scale_fill_manual(tbl$Var1,values = c("coral2", "red")) + 
  theme_bw() + 
  theme (panel.border = element_blank(),legend.title = element_blank(),
         axis.ticks = element_blank(),axis.title.x = element_blank(), 
         axis.title.y = element_blank(), axis.text.x = element_blank(),
         axis.line=element_blank(),panel.grid.major=element_blank(),
         legend.background = element_rect(fill="transparent"), legend.position=c(0.5,0.1), 
         legend.direction="vertical", legend.text=element_text(size = 20)) 

我得到了饼图 enter image description here

您会看到文本方向和图形是不同的。我用coord_polar(theta="y",start = 0, direction = 1)来表示direction = 1是顺时针方向。但是实际上,派的方向是逆时针方向。我做错了什么?

1 个答案:

答案 0 :(得分:2)

您的问题在于如何计算文本位置。与极坐标无关。

让我们看看通过转换data创建的数据框:

> tbl
  Var1 Freq freq      perc       pos
1    a   31   31 0.3924051 0.1962025
2    b   48   79 0.6075949 0.6962025

ggplot(data=tbl, aes(x="", y=perc, fill = factor(Var1))) + 
  geom_bar(width = 0.8, stat="identity") + 
  geom_text(aes(label=paste(round(perc*100),"%",sep=""),y=pos), color="grey20" ,size=15)

plot

这些显然不是文本标签的预期位置。手动计算堆积条形图的标签位置并非易事,但实际上您可以让ggplot为您完成工作,使用position_stack()并指定您首选的vjust值。这是一个实现:

ggplot(data = tbl,
       aes(x = "", y = perc, fill = Var1)) +
  geom_col() +
  geom_text(aes(label = scales::percent(perc, accuracy = 1)),
            position = position_stack(vjust = 0.5),
            color = "grey20", size = 15) +
  coord_polar(theta = "y", direction = -1) +
  scale_fill_manual(values = c("a" = "coral2", "b" = "red")) +
  theme_void() +
  theme(legend.position = "bottom",
        legend.direction = "vertical")

上述代码的其他注意事项:

  1. 使用geom_col()代替geom_bar(stat = "identity");它们是等效的,并且前者看起来更干净;

  2. 使用percent()包中的scales创建百分比标签;比自己动手round()paste()更直观;

  3. coord_polar()的默认参数为start = 0direction = 1。如果您没有更改默认值,则不必指定它们;

  4. 使用命名向量以手动比例指定映射值通常更安全,以防在多个数据集中使用相同的代码,并且并非在所有情况下都显示所有值;

  5. 如果您发现自己重复XXX = element_blank()多次,可能是时候切换到theme_void()并只指定规则例外了。

plot