Search code examples
rggplot2ridgeline-plotggridges

Adding a secondary axis to ggplot2 ggridges (joyplot) to show counts in each bin


I have a ridge plot made with the ggridges package, using the stat = 'binline' argument to plot a histogram for each group. I would like to show the counts for each group on a secondary y-axis at left, with at least one or two axis ticks per group. I cannot find any examples where this has been done. I know it is not straightforward because of the way the y-axis is constructed in ggridges. Is there a relatively easy way to do this?

Code:

set.seed(1)
fakedat <- data.frame(x = sample(1:10, size = 100, replace = TRUE),
                      g = letters[1:4])

library(ggplot2)
library(ggridges)

ggplot(fakedat, aes(x = x, y = g)) +
  geom_density_ridges(stat = 'binline', bins = 10, scale = 0.9) +
  theme_ridges()

Plot:

enter image description here

Desired output would be to have ticks going up the left side that begin at zero at the baseline of each group and show the counts in the histogram bins.


Solution

  • I think you're doing this the hard way. Effectively, what you are trying to do is faceted histograms. Here's a full reprex with a very similar look that doesn't use ggridges at all:

    set.seed(1)
    fakedat <- data.frame(x = sample(1:10, size = 100, replace = TRUE),
                          g = factor(letters[1:4], letters[4:1]))
    
    library(ggplot2)
    
    ggplot(fakedat, aes(x = x, y = ..count..)) +
      stat_bin(geom = "col",  breaks = 0:11 - 0.5, fill = "gray70") +
      stat_bin(geom = "step", breaks = 0:13 - 1) +
      facet_grid(g ~ ., switch = "y") +
      theme_classic() +
      scale_y_continuous(position = "right") +
      scale_x_continuous(breaks = 0:4 * 3) +
      theme(strip.background    = element_blank(),
            axis.text.x         = element_text(size = 16),
            axis.line.x         = element_blank(),
            axis.ticks.x        = element_line(colour = "gray90"),
            axis.ticks.length.x = unit(30, "points"),
            strip.text.y.left   = element_text(angle = 0, size = 16),
            panel.grid.major.x  = element_line(colour = "gray90"))
    

    enter image description here

    Created on 2020-07-27 by the reprex package (v0.3.0)