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.