我有一个像这样的数据集
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))
您会看到文本方向和图形是不同的。我用coord_polar(theta="y",start = 0, direction = 1)
来表示direction = 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)
这些显然不是文本标签的预期位置。手动计算堆积条形图的标签位置并非易事,但实际上您可以让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")
上述代码的其他注意事项:
使用geom_col()
代替geom_bar(stat = "identity")
;它们是等效的,并且前者看起来更干净;
使用percent()
包中的scales
创建百分比标签;比自己动手round()
和paste()
更直观;
coord_polar()
的默认参数为start = 0
和direction = 1
。如果您没有更改默认值,则不必指定它们;
使用命名向量以手动比例指定映射值通常更安全,以防在多个数据集中使用相同的代码,并且并非在所有情况下都显示所有值;
如果您发现自己重复XXX = element_blank()
多次,可能是时候切换到theme_void()
并只指定规则例外了。