Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Force plotly violin plot not to display a violin on zero values

I have measurements from several groups which I would like to plot as violin plots:

set.seed(1)
df <- data.frame(val = c(runif(100,1,5),runif(100,1,5),rep(0,100)),
                 group = c(rep("A",100),rep("B",100),rep("C",100)))

Using R's ggplot2:

library(ggplot2)
ggplot(data = df, aes(x = group, y = val, color = group)) + geom_violin()

I get: enter image description here

But when I try to get the equivalent with R's plotly using:

library(plotly)
plot_ly(x = df$group, y = df$val, split = df$group, type = 'violin', box = list(visible = F), points = F, showlegend = T, color = df$group)

I get: enter image description here

Where group "C" gets an inflated/artificial violin.

Any idea how to deal with this and not by using ggplotly?

like image 616
dan Avatar asked Nov 06 '22 20:11

dan


1 Answers

I did not find a way to fix the behaviour of plotly (probably worth making a bug report for this). A workaround would be to filter your data to only draw violin plots on groups whose range is greater than zero. If you also need to show where the other groups are, you can use a boxplot for these.

To demonstrate, I use library(data.table) for the filtering stage. You could use dplyr or base versions of the same procedure if you prefer:

setDT(df)[, toplot := diff(range(val)) > 0, group]

Now we can plot the groups using different trace styles depending on whether they should have violins or not

plot_ly() %>%
  add_trace(data = df[(toplot)], x = ~group, y = ~val, split = ~group, 
            type = 'violin', box = list(visible = F), points = F) %>% 
  add_boxplot(data = df[(!toplot)], x = ~group, y = ~val, split = ~group)

enter image description here

like image 158
dww Avatar answered Nov 15 '22 11:11

dww