Search code examples
rggplot2facet

ggplot facet with discrete X: drop unused levels and getting scales proportional to number of groups


Let's take the iris dataset as example. But oh, no! We forgot to measure the petals of setosa flowers...

# pivot_longer for plot
i2 <- iris %>%
  pivot_longer(-Species, names_to='parameter', values_to='measure')
i2

# deleting petal measures of setosa
i2 <- i2[-which(i2$Species=='setosa' & i2$parameter=='Petal.Length'),]
i2 <- i2[-which(i2$Species=='setosa' & i2$parameter=='Petal.Width'),]

Now we are plotting the different parameters, faceted by species. As we do not have the petal measures for setosa, we use scales='free_x' so it drops the unused levels. As so:

ggplot(i2, aes(x=parameter, y=measure, colour=parameter)) +
  geom_point() +
  facet_wrap(~Species, nrow=1, scales='free_x')

Now, my issue is: I want the width of each plot to be proportional to the number of groups plotted, i.e. the setosa plot should be about twice thinner than the other species, as only two parameters are plotted.

How can I achieve this?

enter image description here


Solution

  • In facet_grid(), you can set space = "free_x" to have proportional x-axes.

    library(tidyverse)
    
    # pivot_longer for plot
    i2 <- iris %>%
      pivot_longer(-Species, names_to='parameter', values_to='measure')
    
    # deleting petal measures of setosa
    i2 <- i2[-which(i2$Species=='setosa' & i2$parameter=='Petal.Length'),]
    i2 <- i2[-which(i2$Species=='setosa' & i2$parameter=='Petal.Width'),]
    
    ggplot(i2, aes(x=parameter, y=measure, colour=parameter)) +
      geom_point() +
      facet_grid(~Species, scales='free_x', space = "free_x")
    

    Created on 2022-06-06 by the reprex package (v2.0.1)