This question pertains to how to wrap lengthy labels in clustered column/bar chart to have the labels appear on multiple lines (or rows) in multiple panels. Consider the data below
df <- data.frame(group=c("Treated very satisfied", "Treated very satisfied",
"Treated not satisfied","Treated not satisfied",
"Untreated very satisfied","Untreated very satisfied",
"Untreated not satisfied","Untreated not satisfied"),
cost=c("low","high","low","high","low","high","low","high"),
treatment=c("treated","treated","treated","treated",
"untreated","untreated","untreated","untreated") ,
value=c(2.3,5.7,4.0,3.1,9.4,3.1,2.0,-1.6))
We use group as the x axis and value as the y axis. From this data set, the following code is used generate the subsequent chart
#REORDER
df$group <- factor(df$group, levels = c("Treated very satisfied",
"Treated not satisfied",
"Untreated very satisfied",
"Untreated not satisfied"))
ggplot(data=df,aes(y = value, x = group, fill = cost)) +
geom_bar(stat="identity",position='stack') + ylab("Y label") +
theme(legend.direction = "horizontal",legend.position = "bottom",
legend.spacing.x = unit(0.1, 'cm'))+
theme(legend.title=element_blank())+
geom_text(aes(label = ifelse(value !=0, value, "")),
position = position_stack(vjust=0.5))+
facet_grid( ~ treatment)
On the x axis, I expect to see "Treated very satisfied" and "Treated not satisfied" in panel 1 and
"Untreated very satisfied" and "Untreated not satisfied" in panel 2. As shown, these texts overlap, so they cannot be seen clearly. I am looking for a way to format/wrap the texts (not rotate), each into multiple lines (i.e. three lines per each) along the x axis, for example, Treated\n very\n satisfied for all labels in both panels.
I have considered several attempts to resolve this, example using function "str_wrap" in package "stringr" (from Auto wrapping of labels via labeller=label_wrap in ggplot2). However, this does not work due to the panels/clusters in the plot. I would appreciate any help on this.
First I would recommend using scales = "free_x"
in facet_grid
to show only the categories used in each panel. Second. Using the solution in the linked post worked fine for me to wrap the labels.
library(ggplot2)
library(stringr)
df <- data.frame(group=c("Treated very satisfied", "Treated very satisfied",
"Treated not satisfied","Treated not satisfied",
"Untreated very satisfied","Untreated very satisfied",
"Untreated not satisfied","Untreated not satisfied"),
cost=c("low","high","low","high","low","high","low","high"),
treatment=c("treated","treated","treated","treated",
"untreated","untreated","untreated","untreated") ,
value=c(2.3,5.7,4.0,3.1,9.4,3.1,2.0,-1.6))
#REORDER
df$group <- factor(df$group, levels = c("Treated very satisfied",
"Treated not satisfied",
"Untreated very satisfied",
"Untreated not satisfied"))
ggplot(data=df,aes(y = value, x = group, fill = cost)) +
geom_bar(stat="identity",position='stack') + ylab("Y label") +
theme(legend.direction = "horizontal",legend.position = "bottom",
legend.spacing.x = unit(0.1, 'cm'))+
theme(legend.title=element_blank())+
geom_text(aes(label = ifelse(value !=0, value, "")),
position = position_stack(vjust=0.5))+
scale_x_discrete(labels = function(x) str_wrap(x, width = 10)) +
facet_grid( ~ treatment, scales = "free_x")
Created on 2020-06-08 by the reprex package (v0.3.0)