Kate N
Kate N

Reputation: 453

How to create grouped bar plot instead of facet_wrap in R?

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))

enter image description here

I'd like it to look more like this:

enter image description here

Upvotes: 1

Views: 1435

Answers (4)

i94pxoe
i94pxoe

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")

enter image description here

Upvotes: 2

dww
dww

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() 

enter image description here

If you want to remove the gaps between facets, you can use

theme(panel.spacing.y = unit(0,'npc'))

Upvotes: 0

dc37
dc37

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"))

enter image description here

Upvotes: 0

Jordan Hackett
Jordan Hackett

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

Related Questions