Search code examples
rggplot2gplotsggridgesridgeline-plot

R: Weighted Joyplot/Ridgeplot/Density Plot?


I am trying to create a joyplot using the ggridges package (based on ggplot2). The general idea is that a joyplot creates nicely scaled stacked density plots. However, I cannot seem to produce one of these using weighted density. Is there some way of incorporating sampling weights (for weighted density) in the calculation of the densities in the creation of a joyplot?

Here's a link to the documentation for the ggridges package: https://cran.r-project.org/web/packages/ggridges/ggridges.pdf I know a lot of packages based on ggplot can accept additional aesthetics, but I don't know how to add weights to this type of geom object.

Additionally, here is an example of an unweighted joyplot in ggplot. I am trying to convert this to a weighted plot with the density weighted according to pweight.

# Load package, set seed
library(ggplot)
set.seed(1)

# Create an example dataset
dat <- data.frame(group = c(rep("A",100), rep("B",100)),
                  pweight = runif(200),
                  val = runif(200))

# Create an example of an unweighted joyplot
ggplot(dat, aes(x = val, y = group)) + geom_density_ridges(scale= 0.95)

Solution

  • It looks like the way to do this is to use stat_density rather than the default stat_density_ridges. Per the docs you linked to:

    Note that the default stat_density_ridges makes joint density estimation across all datasets. This may not generate the desired result when using faceted plots. As an alternative, you can set stat = "density" to use stat_density. In this case, it is required to add the aesthetic mapping height = ..density.. (see examples).

    Fortunately, stat_density (unlike stat_density_ridges) understands the aesthetic weight and will pass it to the underlying density call. You end up with something like:

    ggplot(dat, aes(x = val, y = group)) +
      geom_density_ridges(aes(height=..density..,  # Notice the additional
                              weight=pweight),     # aes mappings
                          scale= 0.95,
                          stat="density") # and use of stat_density
    

    The ..density.. variable is automatically generated by stat_density.

    Note: It appears that when you use stat_density the x-axis range behaves a little differently: it will trim the density plot to the data range and drop the nice-looking tails. You can easily correct this by manually expanding your x-axis, but I thought it was worth mentioning.