Home > Blockchain >  Violin plot with multiple colors
Violin plot with multiple colors

Time:04-02

I want to generate a violin plot, in which, the different regions are filled with different colors. As an example:

df <- data.frame("data" = runif(1000))
ggplot(df, aes(x ="DATA", y = data))   geom_violin(aes(fill = if_else(data > 0.5, "green","red")))

The commands above generate the violin plot shown in the picture below. The violin plot consists of 2 separated parts. I was expecting one complete shape (i.e. no physical separation) where the upper part (data >0.5) is colored green and the lower part is colored red.

I know there is a coloring problem. But, what I want to ask is:

  • Why the plot comes in 2 separated parts?
  • Is there a way to make it a single "body" as it would be in a regular violin plot?

I found the following solution have a multi-colored violin plot but it did not work in my case: Violin Plot

CodePudding user response:

The linked answer shows a neat way to do this by building the plot and adjusting the underlying grobs, but if you want to do this without grob-hacking, you will need to get your own density curves and draw them with polygons:

df <- data.frame("data" = runif(1000))

dens <- density(df$data)
new_df1 <- data.frame(y = c(dens$x[dens$x < 0.5], rev(dens$x[dens$x < 0.5])),
                      x = c(-dens$y[dens$x < 0.5], rev(dens$y[dens$x < 0.5])),
                      z = 'red2')
new_df2 <- data.frame(y = c(dens$x[dens$x >= 0.5], rev(dens$x[dens$x >= 0.5])),
                      x = c(-dens$y[dens$x >= 0.5], rev(dens$y[dens$x >= 0.5])),
                      z = 'green3')

ggplot(rbind(new_df1, new_df2), aes(x, y, fill = z))   
  geom_polygon()  
  scale_fill_identity()  
  scale_x_continuous(breaks = 0, expand = c(1, 1), labels = 'DATA', name = '')

enter image description here

  • Related