I have a dataframe in R that I want to plot in a faceted ggplot bar chart.
I use this code in ggplot:
ggplot(data_long, aes(x = partei, y = wert, fil
using the comments above I came up with this code:
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)
not as elegant though... but it gives this:
all nicely ordered descending :-)
No need of additionale packages, you can achieve this with plain ggplot:
The complete solution:
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())
further hints:
geom_col()
instead of geom_bar(stat = "identity")
show.legend
argument instead of guides(fill=FALSE)
Because it's sometimes easier to see all code in action, here's a solution for you that generates all plots inside one call to lapply. There were some other issues to figure out (ordering, getting the colors right) and I like a puzzle.
#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)))
The easiest solution would be to use the bar_chart()
function from the ggcharts package. Note that unlike in the answer of @Heroka all subplot have a common x axis.
chart <- ggcharts::bar_chart(
data_long,
partei,
wert,
fill = kat,
facet = kat
)
chart
The result of bar_chart()
is an object of type ggplot
so you can apply any ggplot2
function to it.
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")