I have two PheWAS plots, and the number of categories (x axis, 20 categories) is the same in case of both. I would like to put them on the same plot, mirroring one of them on the y axis, but leaving the x axis titles in the middle.
Example data:
dataset1 <- data.frame(
chr = c(1, 3, 5, 6, 7, 2, 8, 3, 6, 4, 6, 3),
pos = c(445578, 659990, 789689, 678599, 97890, 67899, 9867647, 675890, 799030, 8609000, 789900, 90907878),
p = c(0.05, 0.34, 0.55, 0.05, 0.67, 0.01, 0.34, 0.55, 0.76, 0.88, 0.12, 0.22),
description = factor(c("Metabolic", "Metabolic", "Immunological", "BodyStructures", "Cardiovascular", "Hematological", "Nutritional", "Environment", "Psychiatric", "Cognitive", "Musculoskeletal", "Opthalmological"))
)
dataset2 <- data.frame(
chr = c(1, 3, 5, 6, 7, 2, 8, 3, 6, 4, 6, 3),
pos = c(444358, 647389, 76379, 64789, 1456378, 5647839, 452678, 65789, 657839, 3562789, 15367384, 2647489),
p = c(5e-05, 0.4554, 0.003, 0.6789, 0.6783, 0.00568, 0.789, 0.7799, 0.00457, 0.7899, 0.35678, 0.3678),
description = factor(c("Metabolic", "Metabolic", "Immunological", "BodyStructures", "Cardiovascular", "Hematological", "Nutritional", "Environment", "Psychiatric", "Cognitive", "Musculoskeletal", "Opthalmological"))
)
To create my two plots I use the following script:
Plot 1:
library(ggplot2)
library(RColorBrewer)
colourCount <- length(unique(dataset1$description))
getPalette <- colorRampPalette(brewer.pal(9, "Set1"))
PheWAS_1 <- ggplot(dataset1, aes(x=description, y=-log(p), colour = description)) +
geom_jitter(mapping=aes(x=as.factor(description), y=-log10(p))) +
theme_classic() +
scale_colour_manual(values = getPalette(colourCount)) +
theme(axis.text.x=element_text(angle = 75, vjust = 0.5, hjust=1, size = 10, margin=margin(-30,0,0,0))) +
labs(color="description", size="Effect size", x="Phenotype Group", y="-log10(p-value)") +
geom_hline(yintercept=-log10(7.45E-07), color="gray32", linetype="dashed", size=1, alpha=0.5)+
theme(legend.position = "none") +
theme(axis.title.x = element_text(margin = margin(40, 0, 0, 0)))
Plot 2:
colourCount <- length(unique(dataset2$description))
getPalette <- colorRampPalette(brewer.pal(9, "Set1"))
PheWAS_2 <- ggplot(dataset2, aes(x=description, y=-log(p), colour = description)) +
geom_jitter(mapping=aes(x=as.factor(description), y=-log10(p))) +
theme_classic() +
scale_colour_manual(values = getPalette(colourCount)) +
theme(axis.text.x=element_text(angle = 75, vjust = 0.5, hjust=1, size = 10, margin=margin(-30,0,0,0))) +
labs(color="description", size="Effect size", x="Phenotype Group", y="-log10(p-value)") +
geom_hline(yintercept=-log10(2.83E-06), color="gray32", linetype="dashed", size=1, alpha=0.5)+
theme(legend.position = "none") +
theme(axis.title.x = element_text(margin = margin(40, 0, 0, 0)))
I added an example image, I would like to make a similar one, but with my colours and my titles in between of the two figures.
Flipping the 2nd plot
To achieve this, we need to add two functions:
scale_y_reverse
: This will flip the y
axis; 0 is at the top, 10 at the bottom.scale_x_discrete(position = top)
: This will put the x-axis at the top.Fixing the y-axis limits
It would be best to keep the same y-axis limits for both plots, to make them comparable. As such, we have to supply ylim()
to the first plot. For the second plot, we already have scale_y_reverse
, so we can supply our limits there.
Fixing the x labels
Since you only want the labels to appear once, you'd have to use element_blank()
for theme(axis.text.x)
and theme(axis.title.x)
in the 2nd plot. Similarly, I would remove the x-axis title in the first plot to keep it balanced.
Combining the plots
Now, you want to combine the plots. However, the first plot has a lot of information on the x-axis, while the second plot doesn't. This means they have different heights. I like to use cowplot::plot_grid
for combining plots, because it allows you to set the relative height of the plots. In this case, we can use it to account for the height difference between the two plots.
Final code
PheWAS_1 <- ggplot(dataset1, aes(x = description, y = -log(p), colour = description)) +
geom_jitter() +
theme_classic() +
scale_colour_manual(values = getPalette(colourCount)) +
theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust = 0, size = 10),
axis.title.x = element_blank(),
legend.position = "none") +
labs(color = "description", size = "Effect size", x = "", y = "-log10(p-value)") +
ylim(c(0, 10)) +
geom_hline(yintercept = -log10(7.45E-07), color = "gray32", linetype = "dashed", size = 1, alpha = 0.5)
PheWAS_2 <- ggplot(dataset2, aes(x = description, y = -log(p), colour = description)) +
geom_jitter() +
theme_classic() +
scale_colour_manual(values = getPalette(colourCount)) +
theme(axis.text.x = element_blank(),
axis.title.x = element_blank(),
legend.position = "none") +
labs(color = "description", size = "Effect size", x = "Phenotype Group", y = "-log10(p-value)") +
scale_y_reverse(limits = c(10, 0)) +
scale_x_discrete(position = "top") +
geom_hline(yintercept = -log10(2.83E-06), color = "gray32", linetype = "dashed", size = 1, alpha = 0.5)
cowplot::plot_grid(PheWAS_1, PheWAS_2, ncol = 1, rel_heights = c(1, 0.75))
Final note
The way that you set up your code is that you introduce jitter. This is not a good approach, since ideally the peaks would match between the two plots. You may be better off assigning every row a position on the x-axis.