How to have several facets of different widths displayed correctly on a plot?

Viewed 31

The problem: I have several facets of different widths, and I can't get them to display legibly on the same plot.

The data frame:

> df
# A tibble: 361 × 6
   Letter X     Year     ID NOTID   tot
   <chr>  <chr> <chr> <dbl> <dbl> <dbl>
 1 A      x1    2019      2     2     4
 2 A      x1    2020      1     0     1
 3 B      x1    2019      2     1     3
 4 B      x1    2020      1     7     8
 5 B      x1    2021      1     0     1
 6 C      x1    2014      1     0     1
 7 C      x1    2020      1     1     2
 8 C      x1    2021      2     0     2
 9 C      x1    2015      0     1     1
10 C      x1    2016      0     3     3
# … with 351 more rows

The facets are the Letters (n=27), x axis is Year (n=25 but not all facets have all years --> x can be very different width), y axis is ID/tot and fill is X (n=4).

I have tried different methods:

1: with facet_wrap

a)

df_plot <-na.omit(df)%>%
  ggplot(aes(x=Year, y= ID/tot , fill = X))+
  geom_bar(stat = "identity", position= "dodge")+
  facet_wrap(~Letter,
             scales= "free_x")+
  geom_label(aes(y=0.1, label= paste(round(ID, 1), "/", round(tot, 1), "\n", "=", round((ID/tot)*100, 1),"%")), 
             position = position_dodge(0.9),
             color="black", 
             size=2)+
  scale_y_continuous(labels = scales::percent) ; df_plot

--> the facets have all the same width: enter image description here

b) Then I added:

gp <- ggplotGrob(df_plot)
# optional: take a look at the grob object's layout
gtable::gtable_show_layout(gp)

# get gtable columns corresponding to the facets (5 & 9, in this case)
facet.columns <- gp$layout$l[grepl("panel", gp$layout$name)]

# get the number of unique x-axis values per facet (1 & 3, in this case)
x.var <- sapply(ggplot_build(df_plot)$layout$panel_scales_x,
                function(l) length(l$range$range))

# change the relative widths of the facet columns based on
# how many unique x-axis values are in each facet
gp$widths[facet.columns] <- gp$widths[facet.columns] * x.var

# plot result
grid::grid.draw(gp)

enter image description here

which was a pretty good solution for each facet to have its width, but the problem is that it puts them all on one row, so it's unreadable ...

c) So I did the same thing as above but added nrwo = 4 in facet_wrap and I obtained this plot:

enter image description here

It's getting closer but we can see that it's not yet the right width for each facet...

2: I tried with facet_grid, but even if it seems that each facet have its width, they are all in the same row so it's unreadable...

  ggplot(aes(x=Year, y= ID/tot , fill = X))+
  geom_bar(stat = "identity", position= "dodge")+
  facet_grid(~Letter,
             scales= "free_x",
             space = "free")+
  geom_label(aes(y=0.1, label= paste(round(ID, 1), "/", round(tot, 1), "\n", "=", round((ID/tot)*100, 1),"%")), 
             position = position_dodge(0.9),
             color="black", 
             size=2)+
  scale_y_continuous(labels = scales::percent) ; df_plot

enter image description here

3: And I tried unsuccessfully facet_row and facet_col (ggforce package)... (same kind of result than above).

Does anyone have a solution?... :)

0 Answers
Related