ggplot、facet、piechart:将文本放置在饼图切片的中间 [英] ggplot, facet, piechart: placing text in the middle of pie chart slices
问题描述
我正在尝试使用 ggplot 生成一个多面饼图,但在将文本放置在每个切片的中间时遇到了问题:
dat = read.table(text = "Channel Volume Cnt代理高8344代理中号 5448代理低23823KIOSK 高19275KIOSK 中号 13554KIOSK 低 38293", 标头 = TRUE)vis = ggplot(data=dat, aes(x=factor(1), y=Cnt, fill=Volume)) +geom_bar(stat="identity", position="fill") +coord_polar(theta="y") +facet_grid(Channel~.) +geom_text(aes(x=factor(1), y=Cnt, label=Cnt, ymax=Cnt),位置=位置填充(宽度=1))
输出:
geom_text
需要调整哪些参数,才能在饼图切片中间放置数字标签?
第 1 步:为每个频道创建位置变量
# 以 R 为基础dat$pos <- with(dat, ave(Cnt, Channel, FUN = function(x) cumsum(x) - 0.5*x))# 使用 data.table 包图书馆(数据表)设置DT(数据)dat <- dat[, pos:=cumsum(Cnt)-0.5*Cnt, by="Channel"]# 使用 plyr 包图书馆(plyr)dat <- ddply(dat, .(Channel), 变换, pos=cumsum(Cnt)-0.5*Cnt)# 使用 dplyr 包图书馆(dplyr)dat <- dat %>% group_by(Channel) %>% mutate(pos=cumsum(Cnt)-0.5*Cnt)
第 2 步:创建分面图
库(ggplot2)ggplot(数据 = 数据)+geom_bar(aes(x = "", y = Cnt, fill = Volume), stat = "identity") +geom_text(aes(x = "", y = pos, label = Cnt)) +coord_polar(theta = "y") +facet_grid(Channel ~ ., scales = "free")
结果:
I'm trying to produce a facetted pie-chart with ggplot and facing problems with placing text in the middle of each slice:
dat = read.table(text = "Channel Volume Cnt
AGENT high 8344
AGENT medium 5448
AGENT low 23823
KIOSK high 19275
KIOSK medium 13554
KIOSK low 38293", header=TRUE)
vis = ggplot(data=dat, aes(x=factor(1), y=Cnt, fill=Volume)) +
geom_bar(stat="identity", position="fill") +
coord_polar(theta="y") +
facet_grid(Channel~.) +
geom_text(aes(x=factor(1), y=Cnt, label=Cnt, ymax=Cnt),
position=position_fill(width=1))
The output:
What parameters of geom_text
should be adjusted in order to place numerical labels in the middle of piechart slices?
Related question is Pie plot getting its text on top of each other but it doesn't handle case with facet.
UPDATE: following Paul Hiemstra advice and approach in the question above I changed code as follows:
---> pie_text = dat$Cnt/2 + c(0,cumsum(dat$Cnt)[-length(dat$Cnt)])
vis = ggplot(data=dat, aes(x=factor(1), y=Cnt, fill=Volume)) +
geom_bar(stat="identity", position="fill") +
coord_polar(theta="y") +
facet_grid(Channel~.) +
geom_text(aes(x=factor(1),
---> y=pie_text,
label=Cnt, ymax=Cnt), position=position_fill(width=1))
As I expected tweaking text coordiantes is absolute but it needs be within facet data:
NEW ANSWER: With the introduction of ggplot2 v2.2.0, position_stack()
can be used to position the labels without the need to calculate a position variable first. The following code will give you the same result as the old answer:
ggplot(data = dat, aes(x = "", y = Cnt, fill = Volume)) +
geom_bar(stat = "identity") +
geom_text(aes(label = Cnt), position = position_stack(vjust = 0.5)) +
coord_polar(theta = "y") +
facet_grid(Channel ~ ., scales = "free")
To remove "hollow" center, adapt the code to:
ggplot(data = dat, aes(x = 0, y = Cnt, fill = Volume)) +
geom_bar(stat = "identity") +
geom_text(aes(label = Cnt), position = position_stack(vjust = 0.5)) +
scale_x_continuous(expand = c(0,0)) +
coord_polar(theta = "y") +
facet_grid(Channel ~ ., scales = "free")
OLD ANSWER: The solution to this problem is creating a position variable, which can be done quite easily with base R or with the data.table, plyr or dplyr packages:
Step 1: Creating the position variable for each Channel
# with base R
dat$pos <- with(dat, ave(Cnt, Channel, FUN = function(x) cumsum(x) - 0.5*x))
# with the data.table package
library(data.table)
setDT(dat)
dat <- dat[, pos:=cumsum(Cnt)-0.5*Cnt, by="Channel"]
# with the plyr package
library(plyr)
dat <- ddply(dat, .(Channel), transform, pos=cumsum(Cnt)-0.5*Cnt)
# with the dplyr package
library(dplyr)
dat <- dat %>% group_by(Channel) %>% mutate(pos=cumsum(Cnt)-0.5*Cnt)
Step 2: Creating the facetted plot
library(ggplot2)
ggplot(data = dat) +
geom_bar(aes(x = "", y = Cnt, fill = Volume), stat = "identity") +
geom_text(aes(x = "", y = pos, label = Cnt)) +
coord_polar(theta = "y") +
facet_grid(Channel ~ ., scales = "free")
The result:
这篇关于ggplot、facet、piechart:将文本放置在饼图切片的中间的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!