rggplot2violin-plot

geom_violindot produces obsurd plot


I was using see::geom_violindot to visualize some data:

library(ggplot2)
library(see)

df1 <-
  data.frame(
    Value = c(
      rnorm(25, 0.5 , 0.1),
      rnorm(25, 2.5 , 0.3),
      rnorm(25,-0.1 , 0.05),
      rnorm(25,-0.2 , 0.1)
    ),
    Param = rep(c("a", "b", "c", "d"), each = 25),
    Model = rep("X", 100)
  )
df2 <-
  data.frame(
    Value = c(
      rnorm(25, 0.3, 0.05),
      rnorm(25, 1.8 , 0.5),
      rnorm(25,-0.2 , 0.06),
      rnorm(25,-0.1 , 0.07)
    ),
    Param = rep(c("a", "b", "c", "d"), each = 25),
    Model = rep("Y", 100)
  )
df3 <-
  data.frame(
    Value = c(
      rnorm(25, 0.1, 0.06),
      rnorm(25, 1.2 , 0.4),
      rnorm(25,-0.15 , 0.03),
      rnorm(25,-0.2 , 0.02)
    ),
    Param = rep(c("a", "b", "c", "d"), each = 25),
    Model = rep("Z", 100)
  )

df <- rbind(df1, df2, df3)

ggplot2::ggplot(df) +
  see::geom_violindot(
    ggplot2::aes(x = Param, y = Value, fill = Model),
    scale = "width",
    fill_dots = "black",
    color_dots = "black",
    size_dots = 0.02
  ) +
  ggplot2::theme(aspect.ratio = 3 / 4) +
  ggplot2::labs(x = "Parameter",
                y = "Value")

Created on 2023-08-13 with reprex v2.0.2

I found the plot obsurd because:

  1. For each group of Param, only one binned dots is presented, but each group of Param should have one of its own.
  2. Seems that all four binned dots plots, each has different number of bins, I think the number of bins should at least be the same.

How can I make this plot look right (comply with the points above)? Does this function not support grouped binned dots?


Solution

  • It sounds like you want a raincloud plot with fixed dot bins. You may want to try using geom_dots from ggdist and geom_violinhalf from see:

    library(ggdist)
    library(see)
    
    ggplot(df, aes(x = Param, y = Value, fill = Model, group = Model)) +
      geom_violinhalf(aes(group = interaction(Param, Model)),
                      position = position_dodge(width = 1), scale = "width") +
      geom_dots(position = position_dodge(width = 1), side = "left",
                binwidth = 0.03, fill = "black", size = 0.5) +
      theme(aspect.ratio = 3 / 4) +
      labs(x = "Parameter", y = "Value")
    

    enter image description here