0

I want to compare a number of violinplots. But I am running into a problem for cases where a group is empty: I would like an empty slot plotted so its easier to compare multiple plots.

lets say I have a dataframe:

df = data.frame("x"=rep(c(1:4), 3), y=rep(c(1:4), each=3))
df$y[df$x==3] = NA 

so all of group 3 is NA and I use vioplot to plot it:

library(vioplot)
vioplot(y ~ x , df)

violin plot

then I get the plot without group 3. Is there a way I can plot all groups 1:4 but 3 is just empty?

Thanks

Konrad Rudolph
  • 530,221
  • 131
  • 937
  • 1,214
KGee
  • 771
  • 7
  • 26

3 Answers3

1

For the graph, can you change the NAs to 0? e.g.

df <- df %>% 
  zoo::na.fill(0)

vioplot(y ~ x , df, ylim = c(1, 4))

enter image description here

Tech Commodities
  • 1,884
  • 6
  • 13
  • In some cases I may have 0 values in the df though so I don't really want to hard code them in. I suppose I could set it as some other arbitrary number outside the lims but seems a bit hacky – KGee Jan 11 '22 at 12:26
  • A value like -999 might be the answer. As @Limey says, ggplot2 and geom_violin() may be the easier solution, but requires the addition of other geoms to include the other indicators – Tech Commodities Jan 11 '22 at 12:58
1

Or, using ggplot...

df %>% ggplot() + geom_violin(aes(x=as.factor(x), y=y))

Gives

enter image description here

as does

df %>% ggplot() + geom_violin(aes(x, y=y, group=x))
Limey
  • 10,234
  • 2
  • 12
  • 32
  • In general I would opt for ggplot but in this specific instance I want to stick to base graphics for speed – KGee Jan 12 '22 at 12:04
0

I found a workaround solution for my specific problem using the at argument:

df = data.frame("x"=rep(c(1:4), 3), y=rep(c(1:4), each=3))
df$y[df$x==3] = NA

library(vioplot)
vioplot(y ~ x , df, at=unique(df$x[! is.na(df$y)]), xaxt="n")
axis(1, at=unique(df$x))

enter image description here

KGee
  • 771
  • 7
  • 26