Bob_123
Bob_123

Reputation: 9

Drop unused attribute levels from facet grid

How can I use facet_grid to split this graph into two (horizontally) so that the bottom grid only contains dogs and the top only contains cats.

I have tried using drop and scales but cannot get facet_grid to drop the cats from the dog facet and the dogs from the cat facet.

current graph

ggplot code:

ggplot(data = predictions, mapping = aes(fill=scenario, x=rel_change, y=attribute_level)) + 
  geom_col(position="dodge") +
  theme_bw() +
  scale_y_discrete(limits = c("red cat", "blue cat", "green cat","grey cat", 
                              "red dog", "blue dog", "green dog", "grey dog")) +
  scale_fill_discrete(breaks=c('a', 'b', 'c', 'd','e', 'f', 'g')) +
  theme(axis.text.x = element_text(angle = 45, vjust = 1, hjust=1)) +
  geom_errorbar(aes(xmin = rel_lower, xmax = rel_upper), width = 0.4, position = position_dodge(0.9)) +
  facet_grid(attribute~., scales = "free")

data (example):

# A tibble: 56 × 12
   attribute attribute_level prob_colour      sd lower upper abs_change rel_change rel_lower rel_upper scenario_no group
   <chr>     <chr>                 <dbl>   <dbl> <dbl> <dbl>      <dbl>      <dbl>     <dbl>     <dbl>       <dbl> <chr>
 1 Dog       grey dog              0.309 0.00867 0.296 0.328      0          0         0         0             1.1 a    
 2 Dog       grey dog              0.347 0.0135  0.326 0.378      0          0         0         0             1.2 b    
 3 Dog       grey dog              0.292 0.0113  0.274 0.314      0          0         0         0             1.3 c    
 4 Dog       grey dog              0.316 0.00959 0.299 0.334      0          0         0         0             1.4 d    
 5 Dog       grey dog              0.305 0.00836 0.292 0.324      0          0         0         0             1.5 e    
 6 Dog       grey dog              0.354 0.0132  0.332 0.383      0          0         0         0             1.6 f    
 7 Dog       grey dog              0.288 0.0111  0.269 0.309      0          0         0         0             1.7 g    
 8 Dog       green dog             0.461 0.00752 0.444 0.473      0.152      0.492     0.438     0.532         2.1 a    
 9 Dog       green dog             0.454 0.00846 0.437 0.468      0.107      0.307     0.260     0.349         2.2 b    
10 Dog       green dog             0.465 0.00811 0.450 0.481      0.174      0.596     0.545     0.649         2.3 c    

Upvotes: 0

Views: 114

Answers (1)

stefan
stefan

Reputation: 124128

The issue is that you have set the limits= of the y scale. Hence, scales="free" will have no effect. I can only guess that the reason was to set a specific order of the categories for the y scale. If that is true, then your can achieve both goals by converting attribute_level to a factor with the order of the levels set according to your desired order.

Using a minimal reproducible example base on mtcars.

Let's first reproduce your issue with fixed limits. When I fix the limits scales="free_y" has no effect.

library(ggplot2)

ggplot(mtcars, aes(y = factor(cyl), fill = factor(am))) +
  geom_bar(position = "dodge") +
  scale_y_discrete(limits = levels(factor(mtcars$cyl, levels = c(6, 8, 4)))) +
  facet_grid(gear ~ ., scales = "free_y")

To fix this issue and ensure my desired order of the categories I convert to a factor with the levels set according to my desired order and map this factor on y:

ggplot(mtcars, aes(y = factor(cyl, levels = c(6, 8, 4)), fill = factor(am))) +
  geom_bar(position = "dodge") +
  facet_grid(gear ~ ., scales = "free_y")

Upvotes: 1

Related Questions