ggplot:每个方面的多面条形图中的订单条
ggplot: Order bars in faceted bar chart per facet
我在 R 中有一个数据框,我想在多面 ggplot 条形图中绘制它。
我在 ggplot 中使用了这段代码:
ggplot(data_long, aes(x = partei, y = wert, fill = kat, width=0.75)) +
labs(y = "Wähleranteil [ % ]", x = NULL, fill = NULL) +
geom_bar(stat = "identity") +
facet_wrap(~kat) +
coord_flip() +
guides(fill=FALSE) +
theme_bw() + theme( strip.background = element_blank(),
panel.grid.major = element_line(colour = "grey80"),
panel.border = element_blank(),
axis.ticks = element_line(size = 0),
panel.grid.minor.y = element_blank(),
panel.grid.major.y = element_blank() ) +
theme(legend.position="bottom") +
scale_fill_brewer(palette="Set2")
这将生成此图表:
您可以看到只有最后一个方面是按所需的降序排列的。我希望所有方面都按降序排列,这意味着标签顺序会发生变化。因此我还需要所有方面都有自己的 y 轴标签。
这是我正在使用的数据:
data_long = data.frame(
partei = c("SP", "Grüne", "AL", "BDP", "glp",
"CVP", "EVP", "FDP", "SVP", "EDU", "SP", "Grüne", "AL", "BDP",
"glp", "CVP", "EVP", "FDP", "SVP", "EDU", "SP", "Grüne", "AL",
"BDP", "glp", "CVP", "EVP", "FDP", "SVP", "EDU", "SP", "Grüne",
"AL", "BDP", "glp", "CVP", "EVP", "FDP", "SVP", "EDU", "SP",
"Grüne", "AL", "BDP", "glp", "CVP", "EVP", "FDP", "SVP", "EDU",
"SP", "Grüne", "AL", "BDP", "glp", "CVP", "EVP", "FDP", "SVP",
"EDU", "SP", "Grüne", "AL", "BDP", "glp", "CVP", "EVP", "FDP",
"SVP", "EDU"),
kat = c("kand1", "kand1", "kand1", "kand1", "kand1",
"kand1", "kand1", "kand1", "kand1", "kand1", "kand2", "kand2",
"kand2", "kand2", "kand2", "kand2", "kand2", "kand2", "kand2",
"kand2", "kand3", "kand3", "kand3", "kand3", "kand3", "kand3",
"kand3", "kand3", "kand3", "kand3", "kand4", "kand4", "kand4",
"kand4", "kand4", "kand4", "kand4", "kand4", "kand4", "kand4",
"kand5", "kand5", "kand5", "kand5", "kand5", "kand5", "kand5",
"kand5", "kand5", "kand5", "kand6", "kand6", "kand6", "kand6",
"kand6", "kand6", "kand6", "kand6", "kand6", "kand6", "kand7",
"kand7", "kand7", "kand7", "kand7", "kand7", "kand7", "kand7",
"kand7", "kand7"),
wert = c(95.41, 80.6, 75.77, 54.02, 47.91,
39.01, 36.2, 32.01, 5.71, 1.1, 18.05, 7.15, 9.02, 62.3, 39.18,
42.41, 23.14, 94.66, 29.93, 34.97, 0.51, 0.27, 3.92, 9.21, 2.53,
2.7, 3.52, 23.19, 92.49, 60.64, 52.98, 81.28, 56.42, 7.52, 13.65,
4.06, 9.96, 1.46, 0.94, 0, 7.51, 9.19, 9.94, 25.3, 69.58, 10.59,
9.23, 17.61, 3.6, 3.43, 4.29, 2.37, 7.73, 13.14, 11.67, 75.43,
19.34, 6.52, 2.43, 6.4, 1.87, 2.98, 5.87, 6.7, 1.29, 2.73, 80.91,
1.1, 1.58, 45.47)
)
因为有时更容易查看所有代码的运行情况,这里为您提供了一个解决方案,可以在对 lapply 的一次调用中生成所有图表。还有一些其他问题需要解决(排序、正确设置颜色),我喜欢拼图。
#create list of plots
myplots <- lapply(split(dat,dat$kat), function(x){
#relevel factor partei by wert inside this subset
x$partei <- factor(x$partei, levels=x$partei[order(x$wert,decreasing=F)])
#make the plot
p <- ggplot(x, aes(x = partei, y = wert, fill = kat, width=0.75)) +
geom_bar(stat = "identity") +
scale_fill_discrete(drop=F)+ #to force all levels to be considered, and thus different colors
theme_bw()+
theme(legend.position="none")+
labs(y="Wähleranteil (%)", x="", title=unique(x$kat))+
coord_flip()
})
library(gridExtra)
do.call(grid.arrange,(c(myplots, ncol=3)))
使用上面的评论我想出了这个代码:
names <- levels(unique(data_long$kat))
plist <- list()
plist[]
for (i in 1:length(names)) {
d <- subset(data_long,kat == names[i])
d$partei <- factor(d$partei, levels=d[order(d$wert),]$partei)
p1 <- ggplot(d, aes(x = partei, y = wert, fill = kat, width=0.75)) +
labs(y = "Wähleranteil [ % ]", x = NULL, fill = NULL) +
geom_bar(stat = "identity") +
facet_wrap(~kat) +
scale_y_continuous(limits=c(0, 100)) +
coord_flip() +
guides(fill=FALSE) +
theme_bw() + theme( strip.background = element_blank(),
panel.grid.major = element_line(colour = "grey80"),
panel.border = element_blank(),
axis.ticks = element_line(size = 0),
panel.grid.minor.y = element_blank(),
panel.grid.major.y = element_blank() ) +
theme(legend.position="bottom") +
scale_fill_brewer(palette="Set2")
plist[[names[i]]] = p1
}
do.call("grid.arrange", c(plist, ncol=4)
不过没那么优雅...
但它给出了这个:
全部按降序排列:-)
最简单的解决方案是使用 ggcharts
包中的 bar_chart()
函数。请注意,与@Heroka 的答案不同,所有子图都有一个共同的 x 轴。
chart <- ggcharts::bar_chart(
data_long,
partei,
wert,
fill = kat,
facet = kat
)
chart
bar_chart()
的结果是一个 ggplot
类型的对象,因此您可以对其应用任何 ggplot2
函数。
chart +
labs(y = "Wähleranteil [ % ]", x = NULL, fill = NULL) +
theme_bw() +
theme(
strip.background = element_blank(),
panel.grid.major = element_line(colour = "grey80"),
panel.border = element_blank(),
axis.ticks = element_line(size = 0),
panel.grid.minor.y = element_blank(),
panel.grid.major.y = element_blank(),
legend.position = "none"
) +
scale_fill_brewer(palette = "Set2")
不需要额外的包,你可以用简单的 ggplot 实现:
- 为每一行创建一个附加变量
- 将其作为一个因素,重新排序级别
- 将绘图的标签更改为原始值
完整的解决方案:
data_long %>%
mutate(kat_partei = paste0(kat, '_', partei),
kat_partei = forcats::fct_reorder(kat_partei, wert)) %>%
ggplot(aes(x = kat_partei, y = wert, fill = kat, width=0.75)) +
geom_bar(stat = "identity", show.legend = FALSE) +
scale_x_discrete(name=NULL, labels=function(x) sub('^.*_(.*)$', '\1', x)) +
scale_fill_brewer(palette="Set2") +
coord_flip() +
facet_wrap(~kat, scales='free_y') +
labs(y = "Wähleranteil [ % ]") +
theme_bw() + theme(strip.background = element_blank(),
panel.grid.major = element_line(colour = "grey80"),
panel.border = element_blank(),
axis.ticks = element_line(size = 0),
panel.grid.minor.y = element_blank(),
panel.grid.major.y = element_blank())
进一步提示:
- 使用
geom_col()
代替geom_bar(stat = "identity")
- 使用
show.legend
参数代替 guides(fill=FALSE)
我在 R 中有一个数据框,我想在多面 ggplot 条形图中绘制它。
我在 ggplot 中使用了这段代码:
ggplot(data_long, aes(x = partei, y = wert, fill = kat, width=0.75)) +
labs(y = "Wähleranteil [ % ]", x = NULL, fill = NULL) +
geom_bar(stat = "identity") +
facet_wrap(~kat) +
coord_flip() +
guides(fill=FALSE) +
theme_bw() + theme( strip.background = element_blank(),
panel.grid.major = element_line(colour = "grey80"),
panel.border = element_blank(),
axis.ticks = element_line(size = 0),
panel.grid.minor.y = element_blank(),
panel.grid.major.y = element_blank() ) +
theme(legend.position="bottom") +
scale_fill_brewer(palette="Set2")
这将生成此图表:
您可以看到只有最后一个方面是按所需的降序排列的。我希望所有方面都按降序排列,这意味着标签顺序会发生变化。因此我还需要所有方面都有自己的 y 轴标签。
这是我正在使用的数据:
data_long = data.frame(
partei = c("SP", "Grüne", "AL", "BDP", "glp",
"CVP", "EVP", "FDP", "SVP", "EDU", "SP", "Grüne", "AL", "BDP",
"glp", "CVP", "EVP", "FDP", "SVP", "EDU", "SP", "Grüne", "AL",
"BDP", "glp", "CVP", "EVP", "FDP", "SVP", "EDU", "SP", "Grüne",
"AL", "BDP", "glp", "CVP", "EVP", "FDP", "SVP", "EDU", "SP",
"Grüne", "AL", "BDP", "glp", "CVP", "EVP", "FDP", "SVP", "EDU",
"SP", "Grüne", "AL", "BDP", "glp", "CVP", "EVP", "FDP", "SVP",
"EDU", "SP", "Grüne", "AL", "BDP", "glp", "CVP", "EVP", "FDP",
"SVP", "EDU"),
kat = c("kand1", "kand1", "kand1", "kand1", "kand1",
"kand1", "kand1", "kand1", "kand1", "kand1", "kand2", "kand2",
"kand2", "kand2", "kand2", "kand2", "kand2", "kand2", "kand2",
"kand2", "kand3", "kand3", "kand3", "kand3", "kand3", "kand3",
"kand3", "kand3", "kand3", "kand3", "kand4", "kand4", "kand4",
"kand4", "kand4", "kand4", "kand4", "kand4", "kand4", "kand4",
"kand5", "kand5", "kand5", "kand5", "kand5", "kand5", "kand5",
"kand5", "kand5", "kand5", "kand6", "kand6", "kand6", "kand6",
"kand6", "kand6", "kand6", "kand6", "kand6", "kand6", "kand7",
"kand7", "kand7", "kand7", "kand7", "kand7", "kand7", "kand7",
"kand7", "kand7"),
wert = c(95.41, 80.6, 75.77, 54.02, 47.91,
39.01, 36.2, 32.01, 5.71, 1.1, 18.05, 7.15, 9.02, 62.3, 39.18,
42.41, 23.14, 94.66, 29.93, 34.97, 0.51, 0.27, 3.92, 9.21, 2.53,
2.7, 3.52, 23.19, 92.49, 60.64, 52.98, 81.28, 56.42, 7.52, 13.65,
4.06, 9.96, 1.46, 0.94, 0, 7.51, 9.19, 9.94, 25.3, 69.58, 10.59,
9.23, 17.61, 3.6, 3.43, 4.29, 2.37, 7.73, 13.14, 11.67, 75.43,
19.34, 6.52, 2.43, 6.4, 1.87, 2.98, 5.87, 6.7, 1.29, 2.73, 80.91,
1.1, 1.58, 45.47)
)
因为有时更容易查看所有代码的运行情况,这里为您提供了一个解决方案,可以在对 lapply 的一次调用中生成所有图表。还有一些其他问题需要解决(排序、正确设置颜色),我喜欢拼图。
#create list of plots
myplots <- lapply(split(dat,dat$kat), function(x){
#relevel factor partei by wert inside this subset
x$partei <- factor(x$partei, levels=x$partei[order(x$wert,decreasing=F)])
#make the plot
p <- ggplot(x, aes(x = partei, y = wert, fill = kat, width=0.75)) +
geom_bar(stat = "identity") +
scale_fill_discrete(drop=F)+ #to force all levels to be considered, and thus different colors
theme_bw()+
theme(legend.position="none")+
labs(y="Wähleranteil (%)", x="", title=unique(x$kat))+
coord_flip()
})
library(gridExtra)
do.call(grid.arrange,(c(myplots, ncol=3)))
使用上面的评论我想出了这个代码:
names <- levels(unique(data_long$kat))
plist <- list()
plist[]
for (i in 1:length(names)) {
d <- subset(data_long,kat == names[i])
d$partei <- factor(d$partei, levels=d[order(d$wert),]$partei)
p1 <- ggplot(d, aes(x = partei, y = wert, fill = kat, width=0.75)) +
labs(y = "Wähleranteil [ % ]", x = NULL, fill = NULL) +
geom_bar(stat = "identity") +
facet_wrap(~kat) +
scale_y_continuous(limits=c(0, 100)) +
coord_flip() +
guides(fill=FALSE) +
theme_bw() + theme( strip.background = element_blank(),
panel.grid.major = element_line(colour = "grey80"),
panel.border = element_blank(),
axis.ticks = element_line(size = 0),
panel.grid.minor.y = element_blank(),
panel.grid.major.y = element_blank() ) +
theme(legend.position="bottom") +
scale_fill_brewer(palette="Set2")
plist[[names[i]]] = p1
}
do.call("grid.arrange", c(plist, ncol=4)
不过没那么优雅...
但它给出了这个:
全部按降序排列:-)
最简单的解决方案是使用 ggcharts
包中的 bar_chart()
函数。请注意,与@Heroka 的答案不同,所有子图都有一个共同的 x 轴。
chart <- ggcharts::bar_chart(
data_long,
partei,
wert,
fill = kat,
facet = kat
)
chart
bar_chart()
的结果是一个 ggplot
类型的对象,因此您可以对其应用任何 ggplot2
函数。
chart +
labs(y = "Wähleranteil [ % ]", x = NULL, fill = NULL) +
theme_bw() +
theme(
strip.background = element_blank(),
panel.grid.major = element_line(colour = "grey80"),
panel.border = element_blank(),
axis.ticks = element_line(size = 0),
panel.grid.minor.y = element_blank(),
panel.grid.major.y = element_blank(),
legend.position = "none"
) +
scale_fill_brewer(palette = "Set2")
不需要额外的包,你可以用简单的 ggplot 实现:
- 为每一行创建一个附加变量
- 将其作为一个因素,重新排序级别
- 将绘图的标签更改为原始值
完整的解决方案:
data_long %>%
mutate(kat_partei = paste0(kat, '_', partei),
kat_partei = forcats::fct_reorder(kat_partei, wert)) %>%
ggplot(aes(x = kat_partei, y = wert, fill = kat, width=0.75)) +
geom_bar(stat = "identity", show.legend = FALSE) +
scale_x_discrete(name=NULL, labels=function(x) sub('^.*_(.*)$', '\1', x)) +
scale_fill_brewer(palette="Set2") +
coord_flip() +
facet_wrap(~kat, scales='free_y') +
labs(y = "Wähleranteil [ % ]") +
theme_bw() + theme(strip.background = element_blank(),
panel.grid.major = element_line(colour = "grey80"),
panel.border = element_blank(),
axis.ticks = element_line(size = 0),
panel.grid.minor.y = element_blank(),
panel.grid.major.y = element_blank())
进一步提示:
- 使用
geom_col()
代替geom_bar(stat = "identity")
- 使用
show.legend
参数代替guides(fill=FALSE)