I have a question concerning the fill field in geom_bar
of the ggplot2 package.
我有一个关于ggplot2包的geom_bar中填充字段的问题。
I would like to fill my geom_bar with a variable (in the next example the variable is called var_fill
) but order the geom_plot
with another variable (called clarity
in the example).
我想用变量填充我的geom_bar(在下一个示例中,变量称为var_fill),但是使用另一个变量(在示例中称为clear)命令geom_plot。
How can I do that?
我怎样才能做到这一点?
Thank you very much!
非常感谢你!
The example:
rm(list=ls())
set.seed(1)
library(dplyr)
data_ex <- diamonds %>%
group_by(cut, clarity) %>%
summarise(count = n()) %>%
ungroup() %>%
mutate(var_fill= LETTERS[sample.int(3, 40, replace = TRUE)])
head(data_ex)
# A tibble: 6 x 4
cut clarity count var_fill
<ord> <ord> <int> <chr>
1 Fair I1 210 A
2 Fair SI2 466 B
3 Fair SI1 408 B
4 Fair VS2 261 C
5 Fair VS1 170 A
6 Fair VVS2 69 C
I would like this order of the boxes [clarity] :
我想要这个盒子的顺序[清晰度]:
library(ggplot2)
ggplot(data_ex) +
geom_bar(aes(x = cut, y = count, fill=clarity),stat = "identity", position = "fill", color="black")
with this fill (color) of the boxes [var_fill] :
使用方框[var_fill]的填充(颜色):
ggplot(data_ex) +
geom_bar(aes(x = cut, y = count, fill=var_fill),stat = "identity", position = "fill", color="black")
EDIT1 : answer found by missuse :
EDIT1:missuse发现的答案:
p1 <- ggplot(data_ex) + geom_bar(aes(x = cut, y = count, group = clarity, fill = var_fill), stat = "identity", position = "fill", color="black")+ ggtitle("var fill")
p2 <- ggplot(data_ex) + geom_bar(aes(x = cut, y = count, fill = clarity), stat = "identity", position = "fill", color = "black")+ ggtitle("clarity")
library(cowplot)
cowplot::plot_grid(p1, p2)
EDIT2 : Now i tried to do this with ggmosaic extension with the help of missuse
编辑2:现在我试图用ggmosaic扩展在missuse的帮助下做到这一点
rm(list=ls())
set.seed(1)
library(ggplot2)
library(dplyr)
library(ggmosaic)
data_ex <- diamonds %>%
group_by(cut, clarity) %>%
summarise(count = n()) %>%
ungroup() %>%
mutate(residu= runif(nrow(.), min=-4.5, max=5)) %>%
mutate(residu_classe = case_when(residu < -4~"< -4 (p<0.001)",(residu >= -4 & residu < -2)~"[-4;-2[ (p<0.05)",(residu >= -2 & residu < 2)~"[-2;2[ non significatif",(residu >= 2 & residu < 4)~"[2;4[ (p<0.05)",residu >= 4~">= 4 (p<0.001)")) %>%
mutate(residu_color = case_when(residu < -4~"#D04864",(residu >= -4 & residu < -2)~"#E495A5",(residu >= -2 & residu < 2)~"#CCCCCC",(residu >= 2 & residu < 4)~"#9DA8E2",residu >= 4~"#4A6FE3"))
ggplot(data_ex) +
geom_mosaic(aes(weight= count, x=product(clarity, cut)), fill = data_ex$residu_color, na.rm=T)+
scale_y_productlist() +
theme_classic() +
theme(axis.ticks=element_blank(), axis.line=element_blank())+
labs(x = "cut",y="clarity")
But I would like to add this legend (below) on the right of the plot but I don't know how I could do it because the fill field is outside aes so scale_fill_manual does not work...
但我想在图的右边添加这个图例(下图),但我不知道怎么做,因为填充字段在aes之外,所以scale_fill_manual不起作用...
2 个解决方案
#1
7
Using group aesthetic:
使用群体审美:
p1 <- ggplot(data_ex) +
geom_bar(aes(x = cut, y = count, group = clarity, fill = var_fill),
stat = "identity", position = "fill", color="black") + ggtitle("var fill")
p2 <- ggplot(data_ex) +
geom_bar(aes(x = cut, y = count, fill = clarity), stat = "identity", position = "fill", color = "black")+
ggtitle("clarity")
library(cowplot)
cowplot::plot_grid(p1, p2)
EDIT: with ggmosaic
编辑:与ggmosaic
library(ggmosaic)
p3 <- ggplot(data_ex) +
geom_mosaic(aes(weight= count, x=product(clarity, cut), fill=var_fill), na.rm=T)+
scale_x_productlist()
p4 <- ggplot(data_ex) +
geom_mosaic(aes(weight= count, x=product(clarity, cut), fill=clarity,), na.rm=T)+
scale_x_productlist()
cowplot::plot_grid(p3, p4)
Seems to me for ggmosaic the group is not needed at all, both plots are reversed versions of geom_bar.
在我看来,ggmosaic完全不需要这个组,两个图都是geom_bar的反转版本。
EDIT3:
defining fill outside the aes
fixes the problems such as:
1) X axis readability
2) removes the very small colored lines in the borders of each rectangle
编辑3:在aes外定义填充修复了以下问题:1)X轴可读性2)删除每个矩形边框中的非常小的彩色线条
data_ex %>%
mutate(color = ifelse(var_fill == "A", "#0073C2FF", ifelse(var_fill == "B", "#EFC000FF", "#868686FF"))) -> try2
ggplot(try2) +
geom_mosaic(aes(weight= count, x=product(clarity, cut)), fill = try2$color, na.rm=T)+
scale_x_productlist()
To add y axis labels one needs a bit of wrangling. Here is an approach:
要添加y轴标签,需要进行一些争论。这是一种方法:
ggplot(try2) +
geom_mosaic(aes(weight= count, x=product(clarity, cut)), fill = try2$color, na.rm=T)+
scale_x_productlist()+
scale_y_continuous(sec.axis = dup_axis(labels = unique(try2$clarity),
breaks = try2 %>%
filter(cut == "Ideal") %>%
mutate(count2 = cumsum(count/sum(count)),
lag = lag(count2)) %>%
replace(is.na(.), 0) %>%
rowwise() %>%
mutate(post = sum(count2, lag)/2)%>%
select(post) %>%
unlist()))
EDIT4: adding the legend can be accomplished in two ways.
EDIT4:添加图例可以通过两种方式完成。
1 - by adding a fake layer to generate the legend - however this produces a problem with the x axis labels (they are a combination of cut and fill) hence I defined the manual breaks and labels
1 - 通过添加假图层来生成图例 - 但是这会产生x轴标签的问题(它们是剪切和填充的组合)因此我定义了手动中断和标签
data_ex from OP edit2
来自OP edit2的data_ex
ggplot(data_ex) +
geom_mosaic(aes(weight= count, x=product(clarity, cut), fill = residu_classe), alpha=0, na.rm=T)+
geom_mosaic(aes(weight= count, x=product(clarity, cut)), fill = data_ex$residu_color, na.rm=T)+
scale_y_productlist()+
theme_classic() +
theme(axis.ticks=element_blank(), axis.line=element_blank())+
labs(x = "cut",y="clarity")+
scale_fill_manual(values = unique(data_ex$residu_color), breaks = unique(data_ex$residu_classe))+
guides(fill = guide_legend(override.aes = list(alpha = 1)))+
scale_x_productlist(breaks = data_ex %>%
group_by(cut) %>%
summarise(sumer = sum(count)) %>%
mutate(sumer = cumsum(sumer/sum(sumer)),
lag = lag(sumer)) %>%
replace(is.na(.), 0) %>%
rowwise() %>%
mutate(post = sum(sumer, lag)/2)%>%
select(post) %>%
unlist(), labels = unique(data_ex$cut))
2 - by extracting the legend from one plot and adding it to the other
2 - 从一个图中提取图例并将其添加到另一个图中
library(gtable)
library(gridExtra)
make fake plot for legend:
为传奇制作虚假情节:
gg_pl <- ggplot(data_ex) +
geom_mosaic(aes(weight= count, x=product(clarity, cut), fill = residu_classe), alpha=1, na.rm=T)+
scale_fill_manual(values = unique(data_ex$residu_color), breaks = unique(data_ex$residu_classe))
make the correct plot
制作正确的情节
z = ggplot(data_ex) +
geom_mosaic(aes(weight= count, x=product(clarity, cut)), fill = data_ex$residu_color, na.rm=T)+
scale_y_productlist()+
theme_classic() +
theme(axis.ticks=element_blank(), axis.line=element_blank())+
labs(x = "cut",y="clarity")
a.gplot <- ggplotGrob(gg_pl)
tab <- gtable::gtable_filter(a.gplot, 'guide-box', fixed=TRUE)
gridExtra::grid.arrange(z, tab, nrow = 1, widths = c(4,1))
#2
1
you're almost there! you simply specify the order in the aes, so it would be something like:
你快到了!你只需在aes中指定顺序,所以它会是这样的:
ggplot(data_ex) +
geom_bar(aes(x = cut, y = count, fill=var_fill, order=clarity),stat = "identity", position = "fill", color="black")
and you're good to go.
你很高兴。
#1
7
Using group aesthetic:
使用群体审美:
p1 <- ggplot(data_ex) +
geom_bar(aes(x = cut, y = count, group = clarity, fill = var_fill),
stat = "identity", position = "fill", color="black") + ggtitle("var fill")
p2 <- ggplot(data_ex) +
geom_bar(aes(x = cut, y = count, fill = clarity), stat = "identity", position = "fill", color = "black")+
ggtitle("clarity")
library(cowplot)
cowplot::plot_grid(p1, p2)
EDIT: with ggmosaic
编辑:与ggmosaic
library(ggmosaic)
p3 <- ggplot(data_ex) +
geom_mosaic(aes(weight= count, x=product(clarity, cut), fill=var_fill), na.rm=T)+
scale_x_productlist()
p4 <- ggplot(data_ex) +
geom_mosaic(aes(weight= count, x=product(clarity, cut), fill=clarity,), na.rm=T)+
scale_x_productlist()
cowplot::plot_grid(p3, p4)
Seems to me for ggmosaic the group is not needed at all, both plots are reversed versions of geom_bar.
在我看来,ggmosaic完全不需要这个组,两个图都是geom_bar的反转版本。
EDIT3:
defining fill outside the aes
fixes the problems such as:
1) X axis readability
2) removes the very small colored lines in the borders of each rectangle
编辑3:在aes外定义填充修复了以下问题:1)X轴可读性2)删除每个矩形边框中的非常小的彩色线条
data_ex %>%
mutate(color = ifelse(var_fill == "A", "#0073C2FF", ifelse(var_fill == "B", "#EFC000FF", "#868686FF"))) -> try2
ggplot(try2) +
geom_mosaic(aes(weight= count, x=product(clarity, cut)), fill = try2$color, na.rm=T)+
scale_x_productlist()
To add y axis labels one needs a bit of wrangling. Here is an approach:
要添加y轴标签,需要进行一些争论。这是一种方法:
ggplot(try2) +
geom_mosaic(aes(weight= count, x=product(clarity, cut)), fill = try2$color, na.rm=T)+
scale_x_productlist()+
scale_y_continuous(sec.axis = dup_axis(labels = unique(try2$clarity),
breaks = try2 %>%
filter(cut == "Ideal") %>%
mutate(count2 = cumsum(count/sum(count)),
lag = lag(count2)) %>%
replace(is.na(.), 0) %>%
rowwise() %>%
mutate(post = sum(count2, lag)/2)%>%
select(post) %>%
unlist()))
EDIT4: adding the legend can be accomplished in two ways.
EDIT4:添加图例可以通过两种方式完成。
1 - by adding a fake layer to generate the legend - however this produces a problem with the x axis labels (they are a combination of cut and fill) hence I defined the manual breaks and labels
1 - 通过添加假图层来生成图例 - 但是这会产生x轴标签的问题(它们是剪切和填充的组合)因此我定义了手动中断和标签
data_ex from OP edit2
来自OP edit2的data_ex
ggplot(data_ex) +
geom_mosaic(aes(weight= count, x=product(clarity, cut), fill = residu_classe), alpha=0, na.rm=T)+
geom_mosaic(aes(weight= count, x=product(clarity, cut)), fill = data_ex$residu_color, na.rm=T)+
scale_y_productlist()+
theme_classic() +
theme(axis.ticks=element_blank(), axis.line=element_blank())+
labs(x = "cut",y="clarity")+
scale_fill_manual(values = unique(data_ex$residu_color), breaks = unique(data_ex$residu_classe))+
guides(fill = guide_legend(override.aes = list(alpha = 1)))+
scale_x_productlist(breaks = data_ex %>%
group_by(cut) %>%
summarise(sumer = sum(count)) %>%
mutate(sumer = cumsum(sumer/sum(sumer)),
lag = lag(sumer)) %>%
replace(is.na(.), 0) %>%
rowwise() %>%
mutate(post = sum(sumer, lag)/2)%>%
select(post) %>%
unlist(), labels = unique(data_ex$cut))
2 - by extracting the legend from one plot and adding it to the other
2 - 从一个图中提取图例并将其添加到另一个图中
library(gtable)
library(gridExtra)
make fake plot for legend:
为传奇制作虚假情节:
gg_pl <- ggplot(data_ex) +
geom_mosaic(aes(weight= count, x=product(clarity, cut), fill = residu_classe), alpha=1, na.rm=T)+
scale_fill_manual(values = unique(data_ex$residu_color), breaks = unique(data_ex$residu_classe))
make the correct plot
制作正确的情节
z = ggplot(data_ex) +
geom_mosaic(aes(weight= count, x=product(clarity, cut)), fill = data_ex$residu_color, na.rm=T)+
scale_y_productlist()+
theme_classic() +
theme(axis.ticks=element_blank(), axis.line=element_blank())+
labs(x = "cut",y="clarity")
a.gplot <- ggplotGrob(gg_pl)
tab <- gtable::gtable_filter(a.gplot, 'guide-box', fixed=TRUE)
gridExtra::grid.arrange(z, tab, nrow = 1, widths = c(4,1))
#2
1
you're almost there! you simply specify the order in the aes, so it would be something like:
你快到了!你只需在aes中指定顺序,所以它会是这样的:
ggplot(data_ex) +
geom_bar(aes(x = cut, y = count, fill=var_fill, order=clarity),stat = "identity", position = "fill", color="black")
and you're good to go.
你很高兴。