Reputation: 223
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
Upvotes: 0
Views: 121
Reputation: 19541
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()
Upvotes: 1
Reputation: 227
You can try this approach to combine geom_violin() and geom_line():
library(ggplot2)
# Sample data
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))
# Create a mapping for the x-axis that combines categorical and continuous variables
temps$LvlTemp <- factor(temps$LvlTemp, levels = c("low", "medium", "high"))
df_E_old$LvlTemp <- cut(df_E_old$Temp, breaks=c(0,10,20,40), labels=c("low","medium","high"))
# Create the plot
combined_plot <- ggplot() +
# Violin plot
geom_violin(data = temps, aes(x = LvlTemp, y = Value, fill = LvlTemp, color = LvlTemp),
alpha = 0.5, trim = FALSE) +
# Line plot, aligning the 'Temp' with the x-axis categories of the violin
geom_line(data = df_E_old, aes(x = Temp, y = dE_old), color = "black", size = 1) +
# Add labels and theming
xlab("Temperature Level") +
ylab("Temperature (°C) / dE_old") +
theme_minimal() +
theme(legend.position = "none") +
scale_color_manual(values = c("red", "blue", "purple")) +
scale_fill_manual(values = c("red", "blue", "purple"))
# Show the plot
print(combined_plot)
Upvotes: 0