I would like the levels of two different nested grouping variables to appear on separate lines below the plot, and not in the legend. What I have right now is this code:
data <- read.table(text = "Group Category Value
S1 A 73
S2 A 57
S1 B 7
S2 B 23
S1 C 51
S2 C 87", header = TRUE)
ggplot(data = data, aes(x = Category, y = Value, fill = Group)) +
geom_bar(position = 'dodge') +
geom_text(aes(label = paste(Value, "%")),
position = position_dodge(width = 0.9), vjust = -0.25)
What I would like to have is something like this:
Any ideas?
The strip.position
argument in facet_wrap()
and switch
argument in facet_grid()
since ggplot2 2.2.0 now makes the creation of a simple version of this plot fairly straightforward via faceting. To give the plot the uninterrupted look, set the panel.spacing
to 0.
Here's the example using the dataset with a different number of Groups per Category from @agtudy's answer.
scales = "free_x"
to drop the extra Group from the Categories that don't have it, although this won't always be desirable. strip.position = "bottom"
argument moves the facet labels to the bottom. I removed the strip background all together with strip.background
, but I could see that leaving the strip rectangle would be useful in some situations. width = 1
to make the bars within each Category touch - they'd have spaces between them by default.I also use strip.placement
and strip.background
in theme
to get the strips on the bottom and remove the strip rectangle.
The code for versions of ggplot2_2.2.0 or newer:
ggplot(data = data, aes(x = Group, y = Value, fill = Group)) +
geom_bar(stat = "identity", width = 1) +
geom_text(aes(label = paste(Value, "%")), vjust = -0.25) +
facet_wrap(~Category, strip.position = "bottom", scales = "free_x") +
theme(panel.spacing = unit(0, "lines"),
strip.background = element_blank(),
strip.placement = "outside")
You could use space= "free_x"
in facet_grid()
if you wanted all the bars to be the same width regardless of how many Groups per Category. Note that this uses switch = "x"
instead of strip.position
. You also might want to change the label of the x axis; I wasn't sure what it should be, maybe Category instead of Group?
ggplot(data = data, aes(x = Group, y = Value, fill = Group)) +
geom_bar(stat = "identity", width = 1) +
geom_text(aes(label = paste(Value, "%")), vjust = -0.25) +
facet_grid(~Category, switch = "x", scales = "free_x", space = "free_x") +
theme(panel.spacing = unit(0, "lines"),
strip.background = element_blank(),
strip.placement = "outside") +
xlab("Category")
Older code versions
The code for ggplot2_2.0.0, when this feature was first introduced, was a little different. I've saved it below for posterity:
ggplot(data = data, aes(x = Group, y = Value, fill = Group)) +
geom_bar(stat = "identity") +
geom_text(aes(label = paste(Value, "%")), vjust = -0.25) +
facet_wrap(~Category, switch = "x", scales = "free_x") +
theme(panel.margin = unit(0, "lines"),
strip.background = element_blank())