0

With the R code below,

library(ggplot2)
library(ggridges)
iris$m <- iris$Sepal.Length-5.5
pp <- aggregate(m ~ Species, iris, function(x) 1-ecdf(x)(0))
names(pp)[2] <- 'P'
dat <- merge(iris[, c('Species', 'm')], pp)
dev.new(width=6, height=3)
ggplot(dat, aes(x = m, y = Species, fill=P)) +
  stat_density_ridges(quantile_lines = FALSE, alpha = 0.7) +
  scale_fill_gradientn(colors = c("blue","cyan","gray","gray","yellow","red"), limits = c(0,1))

I get the following ridge plot enter image description here

The color indicates the probability or the area under each density curve above zero on the x-axis (i.e., the value in dat$P). I want to modify the ridge plot so that, if dat$P >=0.5, show the color-coded shading only above 0 on the x-axis; if dat$P < 0.5, show the color-coded shading only below 0 on the x-axis.

Any suggestions?

bluepole
  • 323
  • 1
  • 12

1 Answers1

1

I think you probably need two different layers here:

ggplot(dat, aes(x = m, y = Species, label = P)) +
  geom_density_ridges_gradient(
    aes(fill = if_else(stat(x) > 0, as.numeric(stat(label)), NA_real_),
        linetype = ''),
    quantile_lines = FALSE, 
    data = dat %>% filter(P > 0.5)) +
  geom_density_ridges_gradient(
    aes(fill = if_else(stat(x) < 0, as.numeric(stat(label)), NA_real_),
        linetype = ''),
    quantile_lines = FALSE, 
    data = dat %>% filter(P < 0.5)) +
  labs(fill = "Proportion > 0") +
  scale_fill_gradientn(colors = scales::alpha(c("blue","cyan","gray","gray",
                                                "yellow","red"), 0.7),
                       limits = c(0,1)) +
  scale_linetype_manual(values = 1, name = "XYS") +
  guides(linetype = guide_legend(order = 2, override.aes = list(fill = "white",
                                 col = 'white', size = 0)),
         fill = guide_colorbar(order = 1))

enter image description here

Allan Cameron
  • 147,086
  • 7
  • 49
  • 87
  • Thanks a lot for the quick help! I assume `library(magrittr)` is required, but I got the following error: `Error in filter(., P > 0.5) : object 'P' not found` – bluepole Sep 18 '22 at 20:13
  • 1
    Sorry, it's library(dplyr) or library(tidyverse) you would need here. – Allan Cameron Sep 18 '22 at 20:18
  • Thanks again for the nice solution, @Allan Cameron! Do you mind a small follow-up question: is there an easy way to add a label (e.g., `XYS`) at the bottom of the colorbar? – bluepole Sep 19 '22 at 13:07
  • It depends. Would you still need the label that says "Proportion > 0" at the top? If not, this could be used to say XYS and moved to the bottom. If you want an extra arbitrary label added at the bottom, there are a couple of different ways to do that, but they are a bit hacky. – Allan Cameron Sep 19 '22 at 13:10
  • I would like to keep the original label on the top while adding another one at the bottom. Thanks! – bluepole Sep 19 '22 at 13:18
  • 1
    @bluepole I have added a somewhat hacky solution for adding text here. – Allan Cameron Sep 19 '22 at 13:26