wilkelab/ggridges

[Feature request] : fill the boundaries within

jorvlan opened this issue · 0 comments

Is there a way to assign different colors to the boundaries within each violin?
We have Likert data, and for each 'item' we would like to have a different color representation inside the violin (i.e., the boundaries you see in the figures below i.e., 2nd figure, which are different from the default 'quantiles' boundaries i.e., 1st figure).
Schermafbeelding 2023-01-13 om 4 23 33 PM.

Any suggestions would be appreciated!

Please see the code (steps are included on how to create the figure below)!


library(ggplot2)
library(reshape2)
library(ggridges)

STEP 1:
Create fake data for visualization of likert data

pre <- c(1,1,4,1,1,2,1,1,2,2,1,3,2,1,2,2,2,3,2,4,5,2,3,3,4,4,2,2,5,3,4,3,5,3,3,4,3,2,2,2,4,2,3,2,3,4,4,3,5,1,2,5,2,3,3,5,5,3,1,3,4,2,3,4,3,3,2,3,4,5,3,3,3,4,2,2,4,3,3,5,3,3,2,2,3,3,1,4,4,2,3,4,2,2,1,2,3,3,3,2,1,2,3,3,3,2,3,4,3,4,3,1,4,2,3,2,4,3,3,4,3,3,2,3,4,3,4,3,3,3)

post <- c(1,1,1,1,1,1,1,2,2,1,1,2,2,3,2,2,2,2,2,2,3,3,2,3,1,4,1,2,3,3,5,2,4,3,4,2,3,2,3,2,3,3,3,3,3,3,4,3,5,3,1,3,2,3,3,2,2,3,3,3,4,3,3,3,3,3,3,4,3,3,3,4,3,4,3,3,2,3,3,3,3,3,1,3,3,2,2,4,5,3,3,4,3,3,2,3,3,4,3,4,1,3,4,2,3,2,4,2,3,3,3,3,4,1,3,4,3,3,3,4,3,3,3,3,3,3,3,4,4,5)

STEP 2:
Do some wrangling & labeling to set up the desired structure

likert_data <- data.frame(pre,post)

likert_data$id <- as.factor(as.character(rep(1:dim(likert_data)[1])))

likert_data <- reshape2::melt(likert_data, id.vars = "id")
colnames(likert_data)[2] <- "time"

likert_data$covariate <- -likert_data$value*2

likert_data$group <- c(rep("old", 65), rep("young", 65), rep("old", 65), rep("young", 65))#,
                # rep("old", 65), rep("young", 200), rep("old", 200), rep("young", 200))

likert_data$value[likert_data$group == "young"] <- likert_data$value[likert_data$group == "young"] + 1

likert_data$value[likert_data$group == "old" & likert_data$time == "t2"] <- likert_data$value[likert_data$group == "old" & 
likert_data$time == "t2"] -2

likert_data$jit <- jitter(likert_data$value, amount = .2)

STEP 3:
Create bounds function that will define the boundaries for likert data in each violin

proportions <- table(likert_data$pre)/length(likert_data$pre)

4*0.107 + 1 + 4*0.261

abs_range <- abs(min(likert_data$pre)) + abs(max(likert_data$pre))

4*0.107 + 1 + 4*0.261 + 4*.37 + 4*.18 + 4*.07 #(you don't need the last boundary)

bounds <- function(x, ...){
  
  l_unique_min1 <- length(unique(x))-1
  vec <- as.numeric(rep(0, l_unique_min1))
  proportions <- as.numeric(table(x)/length(x))

  s <- 0
  for (i in 1:l_unique_min1){
    vec[i] <- proportions[i]*l_unique_min1 + s
    s <- vec[i]
  }

  vec <- vec + min(x)
  
  return(vec)
}

STEP 4:
Change dataframe orientation

ct <- reshape2::melt(likert_data)

STEP 5:
Plot the figure

ggplot(ct, aes(x = value, y = variable, fill = variable)) +
  geom_density_ridges(quantile_lines = T, quantile_fun = bounds, position = position_nudge(y=.2)) +
  geom_boxplot(width = .2, position = position_nudge(y= -.2)) +
  geom_point() +
  scale_x_continuous(limits=c(-15, 20)) 

a12bfaec-7260-4470-a072-175870e0fdcc