Search code examples
rggplot2visualization

Customising a GGridges Plot in R


I'd like to create a ggridges-style plot with a few customisations.

I have a dataset with three variables:

  • a likert-like response variable (0:6 responses) called 'RankVar'
  • a node variable (1:9) called 'Node' (this captures a node assignment from a self-organising map).
  • and a cluster variable (A:C) called 'Clus'

In this regard, the response variable is characterised by a node ID and a cluster ID. For example, RankVar responses in Cluster A is characterised by a node ID = 1-4-5 out of the 9 nodes.

In terms of the customised ggridges plot, I'd like to:

  • stack the ridges conditional on cluster labels. Therefore, cluster A should have Node 1-4-5, and have the response variable on the x-axis.

  • I'd also like a blank space in between each cluster. Therefore, after cluster A with node 1-4-5, I'd like a space break (about a binwidth) prior to where cluster B begins node 2-3-7.

  • I'd also like each cluster to be indexed with its own colour. Therefore, nodes 1-4-5 having a different colour on the plot from Nodes 2-3-7.

I've attached my visual (without customisation) and the script that generated it. All help would be greatly appreciated.

Thank you in advance

##################################
#MY RIDGES SO FAR 
###################################

library(tidyverse)
library(ggplot2)
library(ggridges)
library(hrbrthemes)

#######################
#Creating the Ranked Response Variable 
#########################

RankVar = rep(0:5, times = 108) 
RankVar <- sample(RankVar)
RankVar <- as.factor(RankVar)

###############################################
# CREATING NODE ID TO BE ASSIGNED TO EACH OF THE 9 NODES
################################################

Node = rep(1:9, times = 72)
Node <- sample(Node)
Node <- as.factor(Node)

###############################################
#Creating Cluster ID
###############################################

Clus <- rep(LETTERS[1:3], times = 216)
Clus <- noquote(Clus)
Clus

###################
#DATA FRAME
####################

DAT <- data.frame(RankVar, Node)

##############################
#CLUSTER ASSIGNMENTS
##############################

DAT %>% 
  mutate(CLUS = case_when(Node == 1 | Node == 4 | Node == 5 ~ 'A', 
                         Node == 2 | Node == 3 | Node == 7 ~ 'B', 
                         Node == 6 | Node == 8 | Node == 9 ~ 'C'))

#######################################
#VISUALISATION WITHOUT REQUIRED CUSTOMISATION
########################################

ggplot(DAT, aes(x = RankVar, y = Node, fill = Node, group = Node)) +
  geom_density_ridges(alpha = .7, stat = "binline", bins = 30, scale = 0.9) +
  theme_ipsum(axis_title_size = 10) + 
  theme(plot.title = element_text(hjust = 0.5, size = 12, face = "bold"),
        axis.text = element_text(size = 11), legend.position = "none") +
  labs(title = '') +
  scale_x_discrete() +
  scale_fill_manual(values = c("#08519C","#08519C", "#08519C", 
                               "#08519C", "#08519C","#08519C", 
                               "#08519C", "#08519C","#08519C" ))

enter image description here


Solution

  • Is this what you're looking for? If so, you can do most of what you need by faceting on CLUS and using fill=CLUS in the aesthetic. The spacing between panels is controlled by the panel.spacing argument in theme().

    library(tidyverse)
    library(ggplot2)
    library(ggridges)
    library(hrbrthemes)
    #######################
    #Creating the Ranked Response Variable 
    #########################
    
    RankVar = rep(0:5, times = 108) 
    RankVar <- sample(RankVar)
    RankVar <- as.factor(RankVar)
    
    ###############################################
    # CREATING NODE ID TO BE ASSIGNED TO EACH OF THE 9 NODES
    ################################################
    
    Node = rep(1:9, times = 72)
    Node <- sample(Node)
    Node <- as.factor(Node)
    
    ###############################################
    #Creating Cluster ID
    ###############################################
    
    Clus <- rep(LETTERS[1:3], times = 216)
    Clus <- noquote(Clus)
    
    
    ###################
    #DATA FRAME
    ####################
    
    DAT <- data.frame(RankVar, Node)
    
    ##############################
    #CLUSTER ASSIGNMENTS
    ##############################
    
    DAT <- DAT %>% 
      mutate(CLUS = case_when(Node == 1 | Node == 4 | Node == 5 ~ 'A', 
                              Node == 2 | Node == 3 | Node == 7 ~ 'B', 
                              Node == 6 | Node == 8 | Node == 9 ~ 'C'))
    
    ggplot(DAT, aes(x = RankVar, y = Node, fill = CLUS, group = Node)) +
      geom_density_ridges(alpha = .7, stat = "binline", bins = 30, scale = 0.9) +
      theme_ipsum(axis_title_size = 10) + 
      theme(plot.title = element_text(hjust = 0.5, size = 12, face = "bold"),
            axis.text = element_text(size = 11), 
            legend.position = "none", 
            panel.spacing = unit(1, "lines"),
            strip.text = element_text(hjust=.5)) +
      labs(title = '') +
      scale_fill_brewer(palette="Blues") + 
      facet_grid(CLUS~., scales="free_y")
    

    Created on 2024-04-16 with reprex v2.0.2