Reputation: 10956
I'd like to create a 3D waterfall plot using ggplot2
, with the x-/y-axis showing as the ordinary (2D) waterfall plot, and the z-axis as the third dimension of "days on treatment" (bar plot). One example from the paper (Source: doi:10.1093/annonc/mdw656) is shown below (Figure 1 (D)), where the 3D plot is just a combination of the 2D plot (Figure 1 (B)) and the horizontal bar plot (Figure 1 (C)).
Here are some reproducible R codes to create the 2D waterfall plot:
library(ggplot2)
# Mock Data Simulation
subjid = seq(1, 9)
tumor.type = c("CCR", "CCR", "Gastric", "Ovarian", "Ovarian", "CCR", "Breast", "CCR", "Gastric")
per.change = c(42, 26, 20, 10, 5, -5, -10, -20, -50)
days.on.trt = c(20, 40, 60, 45, 70, 80, 100, 90, 120)
dat = data.frame(subjid, tumor.type, per.change, days.on.trt)
dat
# Waterfall Plot
b = ggplot(dat, aes(x=reorder(subjid, -per.change, median), y=per.change, fill=tumor.type)) +
scale_fill_manual(values = c("red3", "gray60", "green4", "dodgerblue3"),
name="Tumor Type") +
labs(x = "Subject ID", y = "Best % Change from Baseline in Tumor Size") +
theme_bw() %+replace%
theme(axis.text.x = element_text(angle=90, hjust = 1),
axis.ticks.x=element_blank(),
axis.title.x = element_text(face="bold", angle=0, size=8),
axis.title.y = element_text(face="bold",angle=90, size=8),
panel.grid.major.x = element_blank(),
legend.justification=c(0.95,0.99), legend.position=c(0.95,0.99),
legend.key = element_rect(fill = "white", 0.1)) +
scale_y_continuous(limits=c(-80, 60), breaks=seq(-80, 60, by=20)) +
coord_cartesian(ylim = c(-80, 60)) +
geom_hline(yintercept = 0) +
geom_hline(yintercept = -30, linetype="dashed", size=1, color="gray30") +
geom_hline(yintercept = 20, linetype="dashed", size=1, color="gray30")
b + geom_bar(stat="identity", width=0.7, position = position_dodge(width=0.4))
And here are some codes (for the same subjects) for the horizontal bar plot:
# Swimmer Plot
ggplot(dat, aes(x=reorder(subjid, per.change), y=days.on.trt)) +
geom_bar(stat='identity') +
labs(x = "Days on Treatment", y = "Subject ID") +
coord_flip()
I appreciate if someone could share some thoughts on how to create the 3D plot as shown in Figure 1 (D) above. Much appreciated!
Upvotes: 2
Views: 2423
Reputation: 26
Second Axeman about ggplot2
not supporting 3D graphics. If you look closely at the article's 3D plot, the color is different from the 2D waterfall plot; tumor size change was crudely drawn on, with visible gaps between the bottom of the bars and the x-axis; and days on treatment do not seem to be physically spaced apart correctly.
This doesn't address your request, but I also gave simulating the dataset and creating the 2D waterfall plot a shot. I prefer if the color theme respects the ordinality of the dosages. Also, this adds the correct x-axis tick labels.
###
# Libraries
###
library(tidyverse)
library(ggplot2)
###
# Simulate data
###
dose.categories <- paste(c(1,5,10,15,20,25), "mg")
disease.categories <- c("CCR", "Gastric", "Ovarian", "Breast")
data <- tibble(
id=sample(20,20),
tchange=sort(runif(n=20,min=-100,max=60), decreasing=T),
dose=dose.categories[c(1,4,2,3,4,1,5,1,5,5,2,3,2,4,3,5,6,5,5,5)],
disease=disease.categories[c(1,1,2,3,3,1,4,4,4,1,4,1,3,2,2,2,4,1,2,2)],
duration=jitter(sort(runif(n=20,min=30,max=120)), amount=30)
) %>%
arrange(id) %>%
mutate(dose=factor(dose, levels=paste(c(1,5,10,15,20,25), "mg")))
###
# 2D waterfall
###
ggplot(data, aes(x=reorder(id, -tchange), y=tchange)) +
geom_bar(aes(fill=dose), stat="identity") +
scale_x_discrete(labels=data$disease[as.numeric(levels(reorder(data$id, -data$tchange)))]) +
scale_fill_brewer(palette="YlGn") +
labs(x="",
y="Tumor size change (%)",
fill="Dose") +
theme(axis.text.x = element_text(angle=90, vjust=0.5, hjust=1),
axis.ticks.x=element_blank(),
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
panel.background = element_blank(),
legend.position="bottom")
Upvotes: 1