Search code examples
rggplot2r-plotly

Strip plot with many columns


How can I replicate a plot like the one below using ggplot?

It is basically a set of strip plots, bound side-by-side. I came across it as an image in a publication, so I don't have the code that made it.

My data source (not plotted) would be something like a list of vectors, similar to those below, each of which can be of a different length.

my_data = list(a=c(1,18,90), b=c(1,5,7,8,80), c=c(1,6), d=c(1,22,35,300))

(That said, using a different data structure would be fine too - e.g. a dataframe with some NA entries)

Stacked strip plots

Thanks for any help!


Solution

  • This seems pretty close:

    library(tidyverse)
    
    set.seed(123)
    IDs <- letters[1:16]
    values <- sample(c(rep(NA, 100000), seq(1e-10, 0, 1e-10)), size = 1600, replace = TRUE)
    test_data <- list(IDs = IDs, values = values)
    
    df <- as.data.frame(test_data)
    ggplot(df, aes(x = IDs, y = values)) +
      geom_point(shape = 95, size = 10) +
      geom_vline(xintercept = seq(0.5, 16.5, 1), colour = "grey75") +
      theme_classic(base_size = 20) +
      scale_x_discrete(expand = c(0.035, 0.035)) +
      scale_y_log10(expand = c(0.001, 0.001),
                    breaks = c(0.0001, 0.001, 0.01, 0.1, 0),
                    labels = expression(10^-4, 10^-3, 10^-2, 10^-1, 10^0)) +
      theme(axis.title = element_blank(),
            axis.ticks.x = element_blank(),
            panel.border = element_rect(colour = "black", fill = NA, size = 2))
    

    example_2.png

    Edit

    Here is a more suitable alternative for the data in your example:

    library(tidyverse)
    my_data = list(a=c(1,18,90), b=c(1,5,7,8,80), c=c(1,6), d=c(1,22,35,300))
    df <- stack(my_data)
    
    ggplot(df, aes(x = ind, y = values)) +
      geom_errorbarh(aes(xmin = as.numeric(ind) + 0.45,
                         xmax = as.numeric(ind) - 0.45),
                     height = 0) +
      geom_vline(xintercept = seq(0.5, 16.5, 1), colour = "grey75") +
      theme_classic(base_size = 20) +
      scale_x_discrete(expand = c(0.125, 0.125)) + # alter these numbers to suit
      theme(axis.title = element_blank(),
            axis.ticks.x = element_blank(),
            panel.border = element_rect(colour = "black", fill = NA, size = 2))
    

    Created on 2021-08-31 by the reprex package (v2.0.1)