使用 ggplot2 根据 R 中的大小缩放网格中的多个饼图
Scaling multiple pie charts in a grid according to their size in R using ggplot2
我想创建一个包含 9 个饼图 (3x3) 的网格,每个饼图都根据其大小进行缩放。
使用 ggplot2
和 cowplot
我能够创建我正在寻找的东西,但我无法进行缩放。
我只是忽略了一个功能还是应该使用另一个包?
我还尝试了 gridExtra 包中的 grid.arrange 和 ggplot 的 facet_grid
函数,但两者都没有产生我正在寻找的东西。
我也发现了一个类似的问题(Pie charts in ggplot2 with variable pie sizes)使用了facet_grid
。
不幸的是,这对我来说不起作用,因为我没有就所有可能的结果比较两个变量。
所以这是我的示例代码:
#sample data
x <- data.frame(c("group01", "group01", "group02", "group02", "group03", "group03",
"group04", "group04", "group05", "group05", "group06", "group06",
"group07", "group07", "group08", "group08", "group09", "group09"),
c("w","m"),
c(8,8,6,10,26,19,27,85,113,70,161,159,127,197,179,170,1042,1230),
c(1,1,1,1,3,3,7,7,11,11,20,20,20,20,22,22,142,142))
colnames(x) <- c("group", "sex", "data", "scale")
#I have divided the group size by the smallest group (group01, 16 people) in order to receive the scaling-variable.
#Please note that I doubled the values here for simplicity-reasons for both men and women per group (for plot-scaling only one value is needed that I calculate
#seperately in the original data in the plot-scaling part underneath).
#In this example I am also going to use the scaling-variable as indicator of the sequence of the plots.
library(ggplot2)
library(cowplot)
#Then I create 9 pie-charts, each one containing one group and showing the quantity of men vs. women in a very simplistic style
#(only the name of the group showing; color of each sex is explained seperately in the according text)
p1 <- ggplot(x[c(1,2),], aes("", y = data, fill = factor(sex), x$scale[1]))+
geom_bar(width = 4, stat="identity") + coord_polar("y", start = 0, direction = 1)+
ggtitle(label=x$group[1])+
theme_classic()+theme(legend.position = "none")+
theme(axis.title=element_blank(),axis.line=element_blank(),axis.ticks=element_blank(),axis.text=element_blank(),plot.background = element_blank(),
plot.title=element_text(color="black",size=10,face="plain",hjust=0.5))
p2 <- ggplot(x[c(3,4),], aes("", y = data, fill = factor(sex), x$scale[3]))+
geom_bar(width = 4, stat="identity") + coord_polar("y", start = 0, direction = 1)+
ggtitle(label=x$group[3])+
theme_classic()+theme(legend.position = "none")+
theme(axis.title=element_blank(),axis.line=element_blank(),axis.ticks=element_blank(),axis.text=element_blank(),plot.background = element_blank(),
plot.title=element_text(color="black",size=10,face="plain",hjust=0.5))
p3 <- ggplot(x[c(5,6),], aes("", y = data, fill = factor(sex), x$scale[5]))+
geom_bar(width = 4, stat="identity") + coord_polar("y", start = 0, direction = 1)+
ggtitle(label=x$group[5])+
theme_classic()+theme(legend.position = "none")+
theme(axis.title=element_blank(),axis.line=element_blank(),axis.ticks=element_blank(),axis.text=element_blank(),plot.background = element_blank(),
plot.title=element_text(color="black",size=10,face="plain",hjust=0.5))
p4 <- ggplot(x[c(7,8),], aes("", y = data, fill = factor(sex), x$scale[7]))+
geom_bar(width = 4, stat="identity") + coord_polar("y", start = 0, direction = 1)+
ggtitle(label=x$group[7])+
theme_classic()+theme(legend.position = "none")+
theme(axis.title=element_blank(),axis.line=element_blank(),axis.ticks=element_blank(),axis.text=element_blank(),plot.background = element_blank(),
plot.title=element_text(color="black",size=10,face="plain",hjust=0.5))
p5 <- ggplot(x[c(9,10),], aes("", y = data, fill = factor(sex), x$scale[9]))+
geom_bar(width = 4, stat="identity") + coord_polar("y", start = 0, direction = 1)+
ggtitle(label=x$group[9])+
theme_classic()+theme(legend.position = "none")+
theme(axis.title=element_blank(),axis.line=element_blank(),axis.ticks=element_blank(),axis.text=element_blank(),plot.background = element_blank(),
plot.title=element_text(color="black",size=10,face="plain",hjust=0.5))
p6 <- ggplot(x[c(11,12),], aes("", y = data, fill = factor(sex), x$scale[11]))+
geom_bar(width = 4, stat="identity") + coord_polar("y", start = 0, direction = 1)+
ggtitle(label=x$group[11])+
theme_classic()+theme(legend.position = "none")+
theme(axis.title=element_blank(),axis.line=element_blank(),axis.ticks=element_blank(),axis.text=element_blank(),plot.background = element_blank(),
plot.title=element_text(color="black",size=10,face="plain",hjust=0.5))
p7 <- ggplot(x[c(13,14),], aes("", y = data, fill = factor(sex), x$scale[13]))+
geom_bar(width = 4, stat="identity") + coord_polar("y", start = 0, direction = 1)+
ggtitle(label=x$group[13])+
theme_classic()+theme(legend.position = "none")+
theme(axis.title=element_blank(),axis.line=element_blank(),axis.ticks=element_blank(),axis.text=element_blank(),plot.background = element_blank(),
plot.title=element_text(color="black",size=10,face="plain",hjust=0.5))
p8 <- ggplot(x[c(15,16),], aes("", y = data, fill = factor(sex), x$scale[15]))+
geom_bar(width = 4, stat="identity") + coord_polar("y", start = 0, direction = 1)+
ggtitle(label=x$group[15])+
theme_classic()+theme(legend.position = "none")+
theme(axis.title=element_blank(),axis.line=element_blank(),axis.ticks=element_blank(),axis.text=element_blank(),plot.background = element_blank(),
plot.title=element_text(color="black",size=10,face="plain",hjust=0.5))
p9 <- ggplot(x[c(17,18),], aes("", y = data, fill = factor(sex), x$scale[17]))+
geom_bar(width = 4, stat="identity") + coord_polar("y", start = 0, direction = 1)+
ggtitle(label=x$group[17])+
theme_classic()+theme(legend.position = "none")+
theme(axis.title=element_blank(),axis.line=element_blank(),axis.ticks=element_blank(),axis.text=element_blank(),plot.background = element_blank(),
plot.title=element_text(color="black",size=10,face="plain",hjust=0.5))
#Using cowplot, I create a grid that contains my plots
plot_grid(p1,p2,p3,p4,p5,p6,p7,p8,p9, align = "h", ncol = 3, nrow = 3)
#But now I want to scale the size of the plots according to their real group size (e.g.
#group01 with 16 people vs. group09 with more than 2000 people)
#In this context, ggplot's facet_grid function produces similar results of what I want to get,
#but since it looks at the data as a whole instead of separating groups from each other, it does not show
#complete pie charts per group
#So is there a possibility to scale each of the 9 charts according to their group size?
这是 plot_grid
产生的:
pie-charts without scaling
使用 rel_widths
参数我只能调整缩放比例,但无法保持 3x3 网格。
plot_grid(p1,p2,p3,p4,p5,p6,p7,p8,p9,
align="h",ncol=(nrow(x)/2),
rel_widths = c(x$scale[1],
x$scale[3],
x$scale[5],
x$scale[7],
x$scale[9],
x$scale[11],
x$scale[13],
x$scale[15],
x$scale[17]))
这就是调整 rel_widths 的作用:
总而言之,我需要的是两者的结合:网格中的缩放饼图。
你走在正确的道路上。问题是您正在为 3x3 输出分配 c(...)
值。您可以通过以下两种方式进行操作:
# Option 1
# individually for each row
plot_upper <- plot_grid(p1, p2, p3, labels = "", ncol = 3, rel_widths = c(1, 1.1, 1.2))
plot_middle <- plot_grid(p4, p5, p6, labels = "", ncol = 3, rel_widths = c(1.3, .3, 1.3))
plot_lower <- plot_grid(p7, p8, p9, labels = "", ncol = 3, rel_widths = c(1.2, 1.1, 1))
plot_grid(plot_upper, plot_middle, plot_lower, ncol = 1, rel_heights = c(1, 2.5, 1.7))
# Option 2
# Set size matrix
sizes <- matrix(c(x$scale[1],
x$scale[3],
x$scale[5],
x$scale[7],
x$scale[9],
x$scale[11],
x$scale[13],
x$scale[15],
x$scale[17]), ncol = 3)
plot_grid(p1,p2,p3,p4,p5,p6,p7,p8,p9, align = "h", ncol = 3, nrow = 3, rel_widths = sizes, rel_heights = sizes)
Here is a link for documentation and here 是一些例子。
因此,如果您将天平调整为矩阵并将其插入选项 2,您应该会得到您想要的。此外,...cbind(...
在定义 data.frame
时是不必要的。
这个呢?
x$scale <- as.numeric(x$scale)
x$data <- as.numeric(x$data)
x$group <- factor(x$group, levels=levels(x$group)[order(x$scale[seq(1,nrow(x),2)])])
ggplot(x, aes(x=scale/2, y = data, fill = factor(sex), width=scale))+
geom_bar(position="fill", stat="identity") + coord_polar("y")+
facet_wrap( ~ group, nrow=3) +
theme_classic()+theme(legend.position = "none")+
theme(axis.title=element_blank(), axis.line=element_blank(),
axis.ticks=element_blank(), axis.text=element_blank(),
plot.background = element_blank(),
plot.title=element_text(color="black",size=10,face="plain",hjust=0.5),
strip.background = element_blank(),
strip.text.x = element_text(color = "transparent") )
我想创建一个包含 9 个饼图 (3x3) 的网格,每个饼图都根据其大小进行缩放。
使用 ggplot2
和 cowplot
我能够创建我正在寻找的东西,但我无法进行缩放。
我只是忽略了一个功能还是应该使用另一个包?
我还尝试了 gridExtra 包中的 grid.arrange 和 ggplot 的 facet_grid
函数,但两者都没有产生我正在寻找的东西。
我也发现了一个类似的问题(Pie charts in ggplot2 with variable pie sizes)使用了facet_grid
。
不幸的是,这对我来说不起作用,因为我没有就所有可能的结果比较两个变量。
所以这是我的示例代码:
#sample data
x <- data.frame(c("group01", "group01", "group02", "group02", "group03", "group03",
"group04", "group04", "group05", "group05", "group06", "group06",
"group07", "group07", "group08", "group08", "group09", "group09"),
c("w","m"),
c(8,8,6,10,26,19,27,85,113,70,161,159,127,197,179,170,1042,1230),
c(1,1,1,1,3,3,7,7,11,11,20,20,20,20,22,22,142,142))
colnames(x) <- c("group", "sex", "data", "scale")
#I have divided the group size by the smallest group (group01, 16 people) in order to receive the scaling-variable.
#Please note that I doubled the values here for simplicity-reasons for both men and women per group (for plot-scaling only one value is needed that I calculate
#seperately in the original data in the plot-scaling part underneath).
#In this example I am also going to use the scaling-variable as indicator of the sequence of the plots.
library(ggplot2)
library(cowplot)
#Then I create 9 pie-charts, each one containing one group and showing the quantity of men vs. women in a very simplistic style
#(only the name of the group showing; color of each sex is explained seperately in the according text)
p1 <- ggplot(x[c(1,2),], aes("", y = data, fill = factor(sex), x$scale[1]))+
geom_bar(width = 4, stat="identity") + coord_polar("y", start = 0, direction = 1)+
ggtitle(label=x$group[1])+
theme_classic()+theme(legend.position = "none")+
theme(axis.title=element_blank(),axis.line=element_blank(),axis.ticks=element_blank(),axis.text=element_blank(),plot.background = element_blank(),
plot.title=element_text(color="black",size=10,face="plain",hjust=0.5))
p2 <- ggplot(x[c(3,4),], aes("", y = data, fill = factor(sex), x$scale[3]))+
geom_bar(width = 4, stat="identity") + coord_polar("y", start = 0, direction = 1)+
ggtitle(label=x$group[3])+
theme_classic()+theme(legend.position = "none")+
theme(axis.title=element_blank(),axis.line=element_blank(),axis.ticks=element_blank(),axis.text=element_blank(),plot.background = element_blank(),
plot.title=element_text(color="black",size=10,face="plain",hjust=0.5))
p3 <- ggplot(x[c(5,6),], aes("", y = data, fill = factor(sex), x$scale[5]))+
geom_bar(width = 4, stat="identity") + coord_polar("y", start = 0, direction = 1)+
ggtitle(label=x$group[5])+
theme_classic()+theme(legend.position = "none")+
theme(axis.title=element_blank(),axis.line=element_blank(),axis.ticks=element_blank(),axis.text=element_blank(),plot.background = element_blank(),
plot.title=element_text(color="black",size=10,face="plain",hjust=0.5))
p4 <- ggplot(x[c(7,8),], aes("", y = data, fill = factor(sex), x$scale[7]))+
geom_bar(width = 4, stat="identity") + coord_polar("y", start = 0, direction = 1)+
ggtitle(label=x$group[7])+
theme_classic()+theme(legend.position = "none")+
theme(axis.title=element_blank(),axis.line=element_blank(),axis.ticks=element_blank(),axis.text=element_blank(),plot.background = element_blank(),
plot.title=element_text(color="black",size=10,face="plain",hjust=0.5))
p5 <- ggplot(x[c(9,10),], aes("", y = data, fill = factor(sex), x$scale[9]))+
geom_bar(width = 4, stat="identity") + coord_polar("y", start = 0, direction = 1)+
ggtitle(label=x$group[9])+
theme_classic()+theme(legend.position = "none")+
theme(axis.title=element_blank(),axis.line=element_blank(),axis.ticks=element_blank(),axis.text=element_blank(),plot.background = element_blank(),
plot.title=element_text(color="black",size=10,face="plain",hjust=0.5))
p6 <- ggplot(x[c(11,12),], aes("", y = data, fill = factor(sex), x$scale[11]))+
geom_bar(width = 4, stat="identity") + coord_polar("y", start = 0, direction = 1)+
ggtitle(label=x$group[11])+
theme_classic()+theme(legend.position = "none")+
theme(axis.title=element_blank(),axis.line=element_blank(),axis.ticks=element_blank(),axis.text=element_blank(),plot.background = element_blank(),
plot.title=element_text(color="black",size=10,face="plain",hjust=0.5))
p7 <- ggplot(x[c(13,14),], aes("", y = data, fill = factor(sex), x$scale[13]))+
geom_bar(width = 4, stat="identity") + coord_polar("y", start = 0, direction = 1)+
ggtitle(label=x$group[13])+
theme_classic()+theme(legend.position = "none")+
theme(axis.title=element_blank(),axis.line=element_blank(),axis.ticks=element_blank(),axis.text=element_blank(),plot.background = element_blank(),
plot.title=element_text(color="black",size=10,face="plain",hjust=0.5))
p8 <- ggplot(x[c(15,16),], aes("", y = data, fill = factor(sex), x$scale[15]))+
geom_bar(width = 4, stat="identity") + coord_polar("y", start = 0, direction = 1)+
ggtitle(label=x$group[15])+
theme_classic()+theme(legend.position = "none")+
theme(axis.title=element_blank(),axis.line=element_blank(),axis.ticks=element_blank(),axis.text=element_blank(),plot.background = element_blank(),
plot.title=element_text(color="black",size=10,face="plain",hjust=0.5))
p9 <- ggplot(x[c(17,18),], aes("", y = data, fill = factor(sex), x$scale[17]))+
geom_bar(width = 4, stat="identity") + coord_polar("y", start = 0, direction = 1)+
ggtitle(label=x$group[17])+
theme_classic()+theme(legend.position = "none")+
theme(axis.title=element_blank(),axis.line=element_blank(),axis.ticks=element_blank(),axis.text=element_blank(),plot.background = element_blank(),
plot.title=element_text(color="black",size=10,face="plain",hjust=0.5))
#Using cowplot, I create a grid that contains my plots
plot_grid(p1,p2,p3,p4,p5,p6,p7,p8,p9, align = "h", ncol = 3, nrow = 3)
#But now I want to scale the size of the plots according to their real group size (e.g.
#group01 with 16 people vs. group09 with more than 2000 people)
#In this context, ggplot's facet_grid function produces similar results of what I want to get,
#but since it looks at the data as a whole instead of separating groups from each other, it does not show
#complete pie charts per group
#So is there a possibility to scale each of the 9 charts according to their group size?
这是 plot_grid
产生的:
pie-charts without scaling
使用 rel_widths
参数我只能调整缩放比例,但无法保持 3x3 网格。
plot_grid(p1,p2,p3,p4,p5,p6,p7,p8,p9,
align="h",ncol=(nrow(x)/2),
rel_widths = c(x$scale[1],
x$scale[3],
x$scale[5],
x$scale[7],
x$scale[9],
x$scale[11],
x$scale[13],
x$scale[15],
x$scale[17]))
这就是调整 rel_widths 的作用:
总而言之,我需要的是两者的结合:网格中的缩放饼图。
你走在正确的道路上。问题是您正在为 3x3 输出分配 c(...)
值。您可以通过以下两种方式进行操作:
# Option 1
# individually for each row
plot_upper <- plot_grid(p1, p2, p3, labels = "", ncol = 3, rel_widths = c(1, 1.1, 1.2))
plot_middle <- plot_grid(p4, p5, p6, labels = "", ncol = 3, rel_widths = c(1.3, .3, 1.3))
plot_lower <- plot_grid(p7, p8, p9, labels = "", ncol = 3, rel_widths = c(1.2, 1.1, 1))
plot_grid(plot_upper, plot_middle, plot_lower, ncol = 1, rel_heights = c(1, 2.5, 1.7))
# Option 2
# Set size matrix
sizes <- matrix(c(x$scale[1],
x$scale[3],
x$scale[5],
x$scale[7],
x$scale[9],
x$scale[11],
x$scale[13],
x$scale[15],
x$scale[17]), ncol = 3)
plot_grid(p1,p2,p3,p4,p5,p6,p7,p8,p9, align = "h", ncol = 3, nrow = 3, rel_widths = sizes, rel_heights = sizes)
Here is a link for documentation and here 是一些例子。
因此,如果您将天平调整为矩阵并将其插入选项 2,您应该会得到您想要的。此外,...cbind(...
在定义 data.frame
时是不必要的。
这个呢?
x$scale <- as.numeric(x$scale)
x$data <- as.numeric(x$data)
x$group <- factor(x$group, levels=levels(x$group)[order(x$scale[seq(1,nrow(x),2)])])
ggplot(x, aes(x=scale/2, y = data, fill = factor(sex), width=scale))+
geom_bar(position="fill", stat="identity") + coord_polar("y")+
facet_wrap( ~ group, nrow=3) +
theme_classic()+theme(legend.position = "none")+
theme(axis.title=element_blank(), axis.line=element_blank(),
axis.ticks=element_blank(), axis.text=element_blank(),
plot.background = element_blank(),
plot.title=element_text(color="black",size=10,face="plain",hjust=0.5),
strip.background = element_blank(),
strip.text.x = element_text(color = "transparent") )