facet_grid scales="free" not working

Hello,

I am using facet_grid and usually scales = "free" works when I have only one parameter ( like in facet_wrap). However, with the following code I cannot make it work correctly:

plot <- PATHWAYS %>%
    dplyr::filter(database == db) %>%
    ggplot(aes(x = gsub("HALLMARK_", "", pathway), y = NES, fill = donor)) +
    geom_bar(stat = "identity", position = "dodge") +
    facet_grid(pathway~group2, scales = "free", space = "free") +
    guides(fill = guide_legend(reverse = TRUE)) +
    theme_bw() %+replace%
    theme(strip.text.y = element_blank(),
          axis.title.y = element_blank(),
          axis.text.y = element_text(size = 12)) +
    coord_flip()

Am I doing something wrong in the code?

Best,

Julia

Hi @jcasadogp ,

What would you expect (want) to see?

Hi @dromano! I Would expect to see grids with different heights, depending on the number of bars inside each of them so each bar has the same height. That is what scales = "free"is supposed to do. I attach a picture found in the internet explaining that parameter:

Taken from here

Thank you very much!

Julia

From your output, it looks like the code did what it was supposed to do, but not what you expected it to do, so to troubleshoot, it would be good to have a better idea of what you wanted it to do. Would you be able to use Excel (or any other software, or even pencil and paper) to draw what you were hoping to see, and post the result here?

Also, could share you data by running this:

PATHWAYS %>%
    dplyr::filter(database == db) %>%
    dput()

and then posting the output here? That would also help folks here to understand what you're trying to do.

Hi!

The code is not doing as it is supposed to as bars do not have the same height. I attach an image where I hope I explain myself better:

As you can also observe in the example I placed before green bars are the same height as orange bars and purple bars, even if each category (North, Central and South America) occupies different spaces of the global plot.

I am sorry, but I cannot share the data here, I hope I could explain myself better without it.

Best,

Julia

I think it will help communication for me to be pedantic; I think its conventional to call the extension/length of a bar in datavis, where that length is meaningful and conveys the measure, 'height' even if its rotated on its side by 90degrees . The non-quantitative extension/length of the bar I would call its 'width' and this has purely aesthetic/readability purpose.

The issue you are having (which you can see does not apply to the working example you linked to) is that all your facets have a single x point and so arent really extending over a range of an x axis ; rather they are dodged off it by their other qualities. scales/free will adjust the facets scale extensions i.e. the min and max of the scale; but in your single point scales there is nothing to adjust per say as there is only a point and not a range.

I expect there is an approach that will produce a more aesthetic visual as you might want but it might take some further thought about how best to achieve it. The lack of example data means a further roadblock to experimenting with it; though I expect I could make a reasonable simulated data if I needed to ; but I don't have that time right now.

This is important to understand: When you dodge a bar, you split it into sub-bars whose aggregate width is the same as the original bar. That why the bar in panel 3 appears 4 times as wide (width is vertical here, as @nirgrahamuk points out) as the individual bars in panel 4..

On solution is to make sure each donor gets their own bar in each panel, sort of like this:

# data extracted from example, saved as toy_data
structure(list(NES = c(-0.8, 0.6, 0.45, 0.5, 0.4, 0.3), pathway = c("ED", 
"AY", "RS", "RS", "RS", "RS"), donor = c("A", "C", "D", "C", 
"B", "A"), group2 = c("P", "O", "P", "P", "P", "P")), class = c("tbl_df", 
"tbl", "data.frame"), row.names = c(NA, -6L)) -> toy_data
toy_data
#>     NES pathway donor group2
#> 1 -0.80      ED     A      P
#> 2  0.60      AY     C      O
#> 3  0.45      RS     D      P
#> 4  0.50      RS     C      P
#> 5  0.40      RS     B      P
#> 6  0.30      RS     A      P
# add new column that combines values of donor and pathway columns
library(tidyverse)
toy_data |> 
  mutate(donor_pathway = str_c(donor, '_', pathway)) -> toy_data

toy_data
#> # A tibble: 6 × 5
#>     NES pathway donor group2 donor_pathway
#>   <dbl> <chr>   <chr> <chr>  <chr>        
#> 1 -0.8  ED      A     P      A_ED         
#> 2  0.6  AY      C     O      C_AY         
#> 3  0.45 RS      D     P      D_RS         
#> 4  0.5  RS      C     P      C_RS         
#> 5  0.4  RS      B     P      B_RS         
#> 6  0.3  RS      A     P      A_RS
# plot
toy_data |> 
  ggplot(aes(x = donor_pathway, y = NES, fill = donor)) +
  geom_bar(stat = "identity", position = "dodge") +
  facet_grid(pathway~group2, 
             scales = "free_y",
             space = "free") +
  guides(fill = guide_legend(reverse = TRUE)) +
  theme_bw() %+replace%
  theme(strip.text.y = element_blank(),
        axis.title.y = element_blank(),
        axis.text.y = element_text(size = 12)) +
  coord_flip()

Created on 2024-06-24 with reprex v2.0.2

Full reprex
structure(list(NES = c(-0.8, 0.6, 0.45, 0.5, 0.4, 0.3), pathway = c("ED", 
"AY", "RS", "RS", "RS", "RS"), donor = c("A", "C", "D", "C", 
"B", "A"), group2 = c("P", "O", "P", "P", "P", "P")), class = c("tbl_df", 
"tbl", "data.frame"), row.names = c(NA, -6L)) -> toy_data

toy_data
#>     NES pathway donor group2
#> 1 -0.80      ED     A      P
#> 2  0.60      AY     C      O
#> 3  0.45      RS     D      P
#> 4  0.50      RS     C      P
#> 5  0.40      RS     B      P
#> 6  0.30      RS     A      P

# add new column that combines values of donor and pathway columns
library(tidyverse)
toy_data |> 
  mutate(donor_pathway = str_c(donor, '_', pathway)) -> toy_data

toy_data
#> # A tibble: 6 × 5
#>     NES pathway donor group2 donor_pathway
#>   <dbl> <chr>   <chr> <chr>  <chr>        
#> 1 -0.8  ED      A     P      A_ED         
#> 2  0.6  AY      C     O      C_AY         
#> 3  0.45 RS      D     P      D_RS         
#> 4  0.5  RS      C     P      C_RS         
#> 5  0.4  RS      B     P      B_RS         
#> 6  0.3  RS      A     P      A_RS

toy_data |> 
  ggplot(aes(x = donor_pathway, y = NES, fill = donor)) +
  geom_bar(stat = "identity", position = "dodge") +
  facet_grid(pathway~group2, 
             scales = "free_y",
             space = "free") +
  guides(fill = guide_legend(reverse = TRUE)) +
  theme_bw() %+replace%
  theme(strip.text.y = element_blank(),
        axis.title.y = element_blank(),
        axis.text.y = element_text(size = 12)) +
  coord_flip()

Created on 2024-06-24 with reprex v2.0.2