Reputation: 453
I have a dataset that has three categorical variables. I know how to use ggplot geom_bar to create a bar plot and facet_wrap. But I want the bars to be grouped by the third categorical variable rather than wrapped. See the plot below. I want the "fall" and "winter" facets to be on top of each other. For example, I want the "fall" results in Grade 10 to be below the "winter" results within one grid. Perhaps I need to structure my data differently.
tmp = data.frame(Grade = rep(1:10, each = 6),
Placement = as.factor(rep(1:5, times = 6)),
Window = rep(c("fall", "winter"), times = 15),
Percent = rnorm(n = 30, mean = 20))
ggplot(data = tmp,
aes(x = Grade, y = Percent, fill = Placement)) +
geom_bar(stat = "identity") +
facet_wrap(vars(Window)) +
coord_flip() +
scale_x_continuous(name = "Grade",
breaks = c(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)) +
scale_y_continuous(name = "Percent",
limits = c(0, 100))
I'd like it to look more like this:
Upvotes: 1
Views: 1435
Reputation: 607
I modified your original dataframe to have percentages directly and to have the correct number of placements per grade (you had 6 "slots" per grade, but placements only from 1 to 5).
Use facet_grid()
instead of facet_wrap()
.
Also, the x
axis should be Window
and the facets are the Grade
variable.
tmp <- data.frame(Grade = as.factor(rep(1:10, each = 6)),
Placement = as.factor(rep(1:6, times = 10)),
Window = rep(c("fall", "winter"), times = 15),
Percent = rnorm(n = 30, mean = 20) / 100)
ggplot(data = tmp, aes(x = Window, y = Percent, fill = Placement)) +
geom_col(position = position_fill()) +
coord_flip() +
facet_grid(Grade~., labeller = label_both, switch = "y") +
geom_text(aes(label = scales::percent(Percent, accuracy = 1)), position = position_fill(vjust = 0.5)) +
scale_y_continuous(labels = scales::percent, expand = c(0,0)) +
labs(x = "", y = "") +
theme(strip.text.y = element_text(angle = 180),
strip.placement = "outside")
Upvotes: 2
Reputation: 31454
facet_grid
probably gives better results than facet_wrap
that some other answers used
tmp$Grade = factor(paste('Grade', tmp$Grade), levels = paste('Grade', 1:10))
ggplot(data = tmp, aes(x = Window, y = Percent, fill = Placement)) +
geom_bar(stat = "identity") +
facet_grid(Grade~., switch = 'y') +
coord_flip()
If you want to remove the gaps between facets, you can use
theme(panel.spacing.y = unit(0,'npc'))
Upvotes: 0
Reputation: 16178
Almost like in the picture (I can't find how to fuse all "Grade" labels on top of the facet_wrap
). I did not change the color pattern but it could be easily done using scale_fill_manual
.
library(ggplot2)
library(dplyr)
tmp %>% arrange(desc(Grade)) %>% mutate(Grade2 = paste("Grade",Grade)) %>%
mutate(Grade2 = factor(Grade2, unique(Grade2))) %>%
ggplot(
aes(x = Window, y = Percent, fill = Placement)) +
geom_bar(stat = "identity") +
coord_flip() +
scale_y_continuous(name = "Percent",
limits = c(0, 100))+
facet_wrap(Grade2~Window, scales = "free_y",strip.position = "left", ncol = 1)+
geom_text(aes(label = paste0(round(Percent,2),"%")),
position = position_stack(vjust = 0.8), size = 2)+
theme(axis.text.y = element_blank(),
axis.title.y = element_blank(),
axis.ticks.y = element_blank(),
strip.text.y = element_text(size = 5),
panel.margin.y = unit(-0.25, "lines"))
Upvotes: 0
Reputation: 749
This is different than what you had, but much closer to the picture you showed:
ggplot(data = tmp,
aes(x = Window, y = Percent, fill = Placement)) +
geom_bar(stat= "identity",position = "fill") +
facet_wrap(~Grade, scales = "free_y", switch = "y", nrow = 10) +
coord_flip() +
scale_y_continuous(labels = scales::percent, expand = c(0,0))
Upvotes: 1