简体   繁体   中英

Violin Plot Width in ggplot

I'm trying to plot one full violin plot next to multiple half-violin plots using ggplot. I'm plotting the full violin plot using geom_violin(), and plotting the half violin plots using geom_violinhalf from the "see" package, with scale = 'width'. However, this produced a figure with the full violin plot appearing significantly thinner than the half-violin plots, as seen in the code below. I've tried the three built-in "scale" options in ggplot.

Is there a way to plot one full violin plot and several half-violin plots using one function? Or is there a different way I can manually set the width of the full violin plot?

Thanks!

#install.packages("vioplot")
#install.packages('ggplot2')
#install.packages('scales')
library(ggplot2)
library(vioplot)
library(scales)

df1 = as.data.frame(matrix(NA, nrow = 1000, ncol = 2))
colnames(df1) = c('x','y')
df1[,2] = rnorm(1000,10,5)
df1[,1] = rep(-5, 1000)
df2 = as.data.frame(matrix(NA, nrow = 10000, ncol = 2))
colnames(df2) = c('x','y')
df2[,1] = sample(seq(0,70,5),10000,replace=TRUE)
df2[,2] = rnorm(10000,10,5)
df = rbind(df1, df2)

ggplot(df, aes(x=x,y=y))+
  geom_violinhalf(data=subset(df,df$x != -5), aes(x=x, group = x), scale = 'width', fill = alpha('red', 0.2), color = alpha('red',0.2))+
  geom_violin(data = subset(df, df$x== -5), color = alpha('red', 0.2), fill = alpha('red', 0.2))+
  geom_point(size = 1.2, col = alpha('grey', 0.2))+
  theme_classic()

EDIT

The previous code was incorrect, apologies. How could the first violin be expanded if the dataframe was instead as follows, with each of the violin plots grouped by 'd' instead of by 'x':

df1 = as.data.frame(matrix(NA, nrow = 10000, ncol = 3))
colnames(df1) = c('d','y','x')
df1[,2] = rnorm(10000,10,5)
df1[,1] = sample(seq(-5,70,.1),10000, replace=TRUE)
for(i in 1:nrow(df1)){
  if(df1[i,'d'] < 0){df1[i,"x"] <- -5}else
    if(df1[i,"d"] >= 0 & df1[i,"d"] < 5){df1[i,"x"] <- 0}else
      if(df1[i,"d"] >= 5 & df1[i,"d"] < 10){df1[i,"x"] <- 5}else
        if(df1[i,"d"] >= 10 & df1[i,"d"] < 15){df1[i,"x"] <- 10}else
          if(df1[i,"d"] >=15 & df1[i,"d"] < 20){df1[i,"x"] <- 15}else
            if(df1[i,"d"] >= 20 & df1[i,"d"] < 25){df1[i,"x"] <- 20}else
              if(df1[i,"d"] >= 25 & df1[i,"d"] < 30){df1[i,"x"] <- 25}else
                if(df1[i,"d"] >= 30 & df1[i,"d"] < 35){df1[i,"x"] <- 30}else
                  if(df1[i,"d"] >= 35 & df1[i,"d"] < 40){df1[i,"x"] <- 35}else
                    if(df1[i,"d"] >= 40 & df1[i,"d"] < 45){df1[i,"x"] <- 40}else
                      if(df1[i,"d"] >= 45 & df1[i,"d"] < 50){df1[i,"x"] <- 45}else
                        if(df1[i,"d"] >= 50 & df1[i,"d"] < 55){df1[i,"x"] <- 50}else
                          if(df1[i,"d"] >= 55 & df1[i,"d"] < 60){df1[i,"x"] <- 55}else
                            if(df1[i,"d"] >= 60 & df1[i,"d"] < 65){df1[i,"x"] <- 60}else
                              if(df1[i,"d"] >= 65 & df1[i,"d"] < 70){df1[i,"x"] <- 65}else
                                if(df1[i,"d"] >= 70 & df1[i,"d"] < 75){df1[i,"x"] <- 70}else
                                  if(df1[i,"d"] >= 75 & df1[i,"d"] < 80){df1[i,"x"] <- 75}}

The widths will equalize by default if you convert x to a factor:

ggplot(df, aes(x=factor(x),y=y)) +
  geom_violinhalf(data=subset(df,df$x != -5), aes(group = x), 
                  scale = 'width', fill = alpha('red', 0.2), 
                  color = alpha('red',0.2)) +
  geom_violin(data = subset(df, df$x== -5), 
              color = alpha('red', 0.2), fill = alpha('red', 0.2)) +
  geom_point(size = 1.2, col = alpha('grey', 0.2)) +
  theme_classic()

在此处输入图片说明

Alternatively, you can keep x numeric and use the width parsmeter of geom_violin . Here I'll set it a bit too wide at width = 8 for demonstration purposes, but the ideal seems to be about width = 5 :

ggplot(df, aes(x = x, y = y)) +
  geom_violinhalf(data = subset(df,df$x != -5), aes(group = x), 
                  scale = 'width', fill = alpha('red', 0.2), 
                  color = alpha('red',0.2)) +
  geom_violin(data = subset(df, df$x == -5), width = 8,
              color = alpha('red', 0.2), fill = alpha('red', 0.2)) +
  geom_point(size = 1.2, col = alpha('grey', 0.2)) +
  theme_classic()

在此处输入图片说明


EDIT

To add the points from column d, we can do:

ggplot(df1, aes(x=x,y=y)) +
  geom_violinhalf(data=subset(df1,df1$x != -5), aes(group = x), 
                  scale = 'width', fill = alpha('red', 0.2), 
                  color = alpha('red',0.2)) +
  geom_violin(data = subset(df1, df1$x== -5), width = 5, 
              color = alpha('red', 0.2), fill = alpha('red', 0.2)) +
  geom_point(aes(x = d), size = 1.2, col = alpha('grey', 0.2)) +
  theme_classic()

在此处输入图片说明

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM