Search code examples
rggplot2tidyversehistogramvisualization

By group mirrored histogram


I would like to get a mirrored histogram by group using ggplot as illustrated in the picture at the bottom.

library(ggplot2)
data2 <- data.frame(
  type = c( rep("Top 1", n_segment),
            rep("Top 2", n_segment),
            rep("Bottom 1", n_segment),
            rep("Bottom 2", n_segment)),
  value = c( rnorm(n_segment, mean=5),
             rnorm(n_segment, mean=12),
             rnorm(n_segment, mean=-5),
             rnorm(n_segment, mean=-12))
)

# Represent it
data2 %>%
  ggplot( aes(x=value, fill=type)) +
  geom_density( color="#e9ecef", alpha=0.6) 

For now I am getting this:

enter image description here

But I would like to mirror them as follows: enter image description here


Solution

  • Try this approach. You can work with ..density.. and adjust geom_density() around different subsets of data enabling data option and smartly filtering which values go up and down. Here the code:

    library(ggplot2)
    library(dplyr)
    # Represent it
    data2 %>%
      ggplot( aes(x=value, fill=type,group=type)) +
      geom_density(aes(y=-1*..density..),alpha=0.6,
                   data = ~ subset(., type %in% c("Bottom 1","Bottom 2")))+
      geom_density(aes(y=..density..),alpha=0.6,
                   data = ~ subset(., !type %in% c("Bottom 1","Bottom 2")))+
      ylab('density')
    

    Output:

    enter image description here

    If you want to avoid lines, try this:

    # Represent it 2
    data2 %>%
      ggplot( aes(x=value, fill=type,group=type)) +
      geom_density(aes(y=-1*..density..),alpha=0.6,color='transparent',
                   data = ~ subset(., type %in% c("Bottom 1","Bottom 2")))+
      geom_density(aes(y=..density..),alpha=0.6,color='transparent',
                   data = ~ subset(., !type %in% c("Bottom 1","Bottom 2")))+
      ylab('density')
    

    Output:

    enter image description here