I would like to draw on the same plot a curve and some violin plots. Is it possible ? For now, I'm only able to draw them separately, one of the top of the other as in the example code.
Here is an example code (with trim=TRUE
the alignment is better, but I would like to keep trim=FALSE
)
library("ggpubr")
library("ggplot2")
temps <- data.frame("LvlTemp"= c(rep("low", 10),
rep("medium", 15),
rep("high", 20)),
"Value" = c(runif(10, 0, 30), runif(15, 5, 40),runif(20, 15, 40) ))
df_E_old <- data.frame("Temp"=0:40, "dE_old"=sqrt(0:40))
Vplot <- ggplot(temps, aes(x = LvlTemp, y = Value, fill=LvlTemp, color=LvlTemp, alpha=0.5,
ymin=0, ymax = 40)) +
geom_violin(trim=FALSE) +
coord_flip() + # This switch X and Y axis and allows to get the horizontal version
xlab("") +
ylab("Temperature (°C)") +
theme(
legend.position="none" # no legend, don't know yet
) +
scale_x_discrete(limits=c("low", "medium", "high")) +
scale_color_manual(values=c("red", "blue", "purple"))+
scale_fill_manual(values=c("red", "blue", "purple"))
Lplot <- ggplot(df_E_old, aes(x=Temp, y=dE_old)) +
geom_line()
ggarrange(Vplot, Lplot,
ncol = 1, nrow = 2, align="v")
Here is an idea of what I want to obtain
EDIT : I succeed thanks to the example of liaifat85
library("ggpubr")
library("ggplot2")
temps <- data.frame("LvlTemp"= c(rep("low", 10),
rep("medium", 15),
rep("high", 20)),
"Value" = c(runif(10, 0, 30), runif(15, 5, 40),runif(20, 15, 40) ))
df_E_old <- data.frame("Temp"=0:40, "dE_old"=sqrt(0:40))
temps$LvlTemp <- factor(temps$LvlTemp, levels = c("low", "medium", "high"))
diviseur <- 1
ggplot() +
geom_path(data = df_E_old, aes(x = dE_old, y = Temp), color = "black", linewidth = 1) +
geom_violin(data = temps, aes(x = as.numeric(LvlTemp)/diviseur, y = Value,
fill = LvlTemp, color = LvlTemp),
alpha = 0.5, trim = TRUE) +
coord_flip() + # This switch X and Y axis and allows to get the horizontal version
# Add labels and theming
xlab("Development rate") +
ylab("Temperature (°C)") +
theme_minimal() +
theme(legend.position = "none") +
scale_color_manual(values = c("blue", "purple", "red")) +
scale_fill_manual(values = c("blue", "purple", "red"))
I still have to do some work about diviseur
or something else to automatically have the right range depending on the values of the curve
It seems you just need to create the x-axis (y-axis after coord flip) values for the violin plot, which, for three groups, would be the means of the development rate for each group.
df_E_old <- data.frame("Temp"=0:40, "dE_old"=sqrt(0:40)) |>
mutate(LvlTemp=c(rep("low", 10), rep("medium", 11), rep("high", 20))) |>
mutate(mean_dE=mean(dE_old), .by=LvlTemp)
ggplot(df_E_old, aes(y = Temp)) +
geom_path(aes(x = dE_old), color = "black", linewidth = 1) +
geom_violin(aes(x = mean_dE, fill = LvlTemp, color = LvlTemp),
alpha = 0.5, trim = TRUE) +
coord_flip()