I am trying to put two plots side-by-side with a shared legend and labelled with "A" and "B" in the upper left corners of the plots. I've used this code for other graphs, but am getting the following error for these two graphs: Error in plot$plot_env : $ operator is invalid for atomic vectors
. I'm wondering if this is because one of my graphs has an inset that I created using ggdraw
and draw_plot
. I was able to combine the graphs using the patchwork
package but they didn't line up well and I'm not sure how I would add the text labels (A,B). I'm open to other ways of doing this, and sincerely appreciate any help!
Code:
# data
pca_reduced_data=structure(list(PC1 = c(-3.66082553456275, -3.61675752888208,
-3.55566899817572, 3.38109907209222), PC2 = c(12.8802103126013,
-0.713309237957807, 0.731508008920202, 0.667782339409592), PC3 = c(16.3272068024728,
-1.67657983890727, 0.383456217270273, -2.16098780775346), pop = structure(c(3L,
1L, 4L, 2L), levels = c("JI", "MSI", "QC", "WB"), class = "factor")), class = c("grouped_df",
"tbl_df", "tbl", "data.frame"), row.names = c(NA, -4L), groups = structure(list(
pop = structure(1:4, levels = c("JI", "MSI", "QC", "WB"), class = "factor"),
.rows = structure(list(2L, 4L, 1L, 3L), ptype = integer(0), class = c("vctrs_list_of",
"vctrs_vctr", "list"))), row.names = c(NA, -4L), .drop = TRUE, class = c("tbl_df",
"tbl", "data.frame")))
dapc_reduced_data=structure(list(LD1 = c(-5.40157574377924, -4.74765500081979,
-4.37012382945435, 5.28806893654893), LD2 = c(-2.23493787652176,
0.448609871281537, 1.97547816809835, 0.267065358033146), pop = structure(c(4L,
1L, 3L, 2L), levels = c("JI", "MSI", "QC", "WB"), class = "factor")), class = c("grouped_df",
"tbl_df", "tbl", "data.frame"), row.names = c(NA, -4L), groups = structure(list(
pop = structure(1:4, levels = c("JI", "MSI", "QC", "WB"), class = "factor"),
.rows = structure(list(2L, 4L, 3L, 1L), ptype = integer(0), class = c("vctrs_list_of",
"vctrs_vctr", "list"))), row.names = c(NA, -4L), .drop = TRUE, class = c("tbl_df",
"tbl", "data.frame")))
scree_inset_data=c(16.9988640297922, 12.379842241201, 12.1899415304287, 11.7483168771955,
11.6839091223602, 11.4471012210121, 11.3883159867078, 11.3509158077438,
11.3079585639685, 11.2047232293121, 11.1890745189968, 11.1490209187405,
11.1453621634354, 11.1074525657331, 11.0652283253512, 11.007749361895,
10.9904579388938, 10.9556858169499, 10.9037335461794, 10.8612546878365,
10.7864281895125, 10.7428161027248, 10.7212418120642, 10.7090363195108,
10.6939001307477, 10.6686069926198, 10.6107363135009, 10.5926342594916,
10.5511433152624, 10.539778618528, 10.5360072153117, 10.4570282939901,
10.4261884758465, 10.4113419352431, 10.3940692516186, 10.3692642501954,
10.3558553546518, 10.33072314101, 10.2761376733371, 10.2685882165183,
10.2279353841831, 10.2171124489118, 10.1710273107829, 10.1640158162311,
10.1064954408422, 10.0757021419861, 10.0728659023097, 10.0539821376689,
10.0019697899667, 9.99952901544393, 9.96520209216404, 9.94138414635945,
9.92144848871057, 9.88565404783232, 9.84191493031826, 9.82035556737913,
9.80154283721816, 9.79445289707198, 9.76087692408792, 9.72588004880728,
9.69867710858197, 9.66982435789276, 9.65952875732623, 9.64055226141272,
9.59162849868911, 9.58439530146837, 9.54423416598424, 9.54069481451019,
9.50801148211689, 9.50002859485689, 9.47048020384415, 9.45117375786014,
9.41892889796326, 9.38298694689175, 9.37631630559629, 9.35256491594043,
9.33367119876701, 9.31787427162355, 9.28681296686234, 9.27105520780603,
9.25465146089899, 9.21917155463335, 9.19088683804238, 9.17042860266981,
9.13192244921806, 9.08544711143804, 9.06945676972503, 9.05068576641311,
9.02277917261323, 9.01652629566344, 8.99604408015491, 8.95217545543665,
8.9340566397891, 8.8897856776607, 8.88331211898674, 8.84791823056101,
8.81372548086933, 8.76645663026873, 8.76060641579664, 8.70843733020328,
8.68793222517238, 8.67163732698248, 8.62874066805493, 8.60283738458434,
8.58735462799861, 8.56701017870646, 8.55921756543008, 8.54251288433883,
8.52199719192059, 8.48457597151362, 8.4632503790919, 8.45299625722206,
8.4029094356594, 8.37756002962608, 8.35370569938004, 8.24943928971093,
8.204534716839, 8.16261882714644, 8.14029523227711, 8.08560275060754,
8.02567138490603, 7.44847495582657, 6.99559930158964)
# define color vector
library(RColorBrewer)
cols <- brewer.pal(n=4, name = "Dark2")
#create pca scatterplot
set.seed(19)
pca_scatterplot <- ggplot(pca_reduced_data, aes(x=PC1, y=PC2, colour=pop, shape=pop))
pca_scatterplot <- pca_scatterplot + theme_classic()
pca_scatterplot <- pca_scatterplot + theme(axis.text.x=element_blank(), axis.ticks.x=element_blank(),
axis.text.y=element_blank(), axis.ticks.y=element_blank())
pca_scatterplot <- pca_scatterplot + geom_point(size=2)
pca_scatterplot <- pca_scatterplot + scale_color_manual(values = cols)
pca_scatterplot <- pca_scatterplot + geom_hline(yintercept = 0)
pca_scatterplot <- pca_scatterplot + geom_vline(xintercept = 0)
pca_scatterplot <- pca_scatterplot + labs(color = "Pop", shape = "Pop")
# create dapc scree plot
# Create a data frame for the scree plot
scree_data2 <- data.frame(Component = 1:length(scree_inset_data), Eigenvalue = scree_inset_data)
scree_data2$Highlight <- c(rep("yes", 30), rep("no", nrow(scree_data2) - 30))
View(scree_data2)
# Create the scree plot using ggplot2
scree_inset_plot <- ggplot(scree_data2, aes(x = Component, y = Eigenvalue, fill = Highlight)) +
geom_bar(stat = "identity") +
theme_classic() +
theme(plot.title = element_text(hjust = 0.5, size=10),
axis.text.x=element_blank(), axis.ticks.x=element_blank(),
axis.text.y=element_blank(), axis.ticks.y=element_blank(),
legend.position="none") +
labs(title="PCA Eigenvalues", x=NULL, y =NULL) +
scale_fill_manual(values = c("no" = "lightgray", "yes" = "darkgray"))
# Create a dapc scatterplot
set.seed(19)
dapc_scatterplot <- ggplot(dapc_reduced_data, aes(x=LD1, y=LD2, colour=pop, shape=pop))
dapc_scatterplot <- dapc_scatterplot + theme_classic() + theme(axis.text.x=element_blank(), axis.ticks.x=element_blank(),
axis.text.y=element_blank(), axis.ticks.y=element_blank(), legend.position="none")
dapc_scatterplot <- dapc_scatterplot + geom_point(size=2)
dapc_scatterplot <- dapc_scatterplot + scale_color_manual(values = cols)
dapc_scatterplot <- dapc_scatterplot + geom_hline(yintercept = 0)
dapc_scatterplot <- dapc_scatterplot + geom_vline(xintercept = 0)
dapc_scatterplot <- dapc_scatterplot + labs(color = "Pop", shape = "Pop")
# Combine the dapc with scree plot inset
library(cowplot)
dapc_inset_scree <-
ggdraw() +
draw_plot(dapc_scatterplot) +
draw_plot(scree_inset_plot, x = 0.6, y = .75, width = .25, height = .25)
# graph the pca and dapc together
library(grid) # for the textGrob() function
library(tidyverse)
library(ggpubr)
library(reshape2)
pca_dapc_combined_plot <-ggarrange(pca_scatterplot,
dapc_inset_scree,
labels = c("A","B"), hjust = c(-2,-2.5),vjust = 1,
ncol = 2, nrow = 1,
common.legend = TRUE, legend = "right",
align = "hv",
font.label = list(size = 10, color = "black", face = "bold", family = NULL, position = "top"),
widths = 2, heights = 1)
Unfortunately I can't reproduce the error you mentioned. But to fix the alignment of your plots (I think you are right that this is related to ggdraw
) you could add your inset plot using annotation_custom
(but patchwork::inset_element
worked also fine for me). Additionally, instead of using hjust
to shift the labels which in my opinion almost never works I would suggest to use annotation_custom
too, even if it requires some more effort.
library(ggplot2)
library(patchwork)
library(grid)
pca_scatterplot <- pca_scatterplot +
annotation_custom(
grid::textGrob(
label = "A",
x = unit(0, "npc") - unit(2, "pt"),
y = unit(1, "npc") + unit(2, "pt"),
hjust = 1, vjust = 0,
gp = grid::gpar(
fontface = "bold"
)
)
)
dapc_inset_scree <-
dapc_scatterplot +
annotation_custom(
ggplotGrob(
scree_inset_plot
),
xmin = .5,
ymin = .5
) +
annotation_custom(
grid::textGrob(
label = "B",
x = unit(0, "npc") - unit(2, "pt"),
y = unit(1, "npc") + unit(2, "pt"),
hjust = 1, vjust = 0,
gp = grid::gpar(
fontface = "bold"
)
)
)
pca_scatterplot +
dapc_inset_scree +
plot_layout(guides = "collect") &
coord_cartesian(clip = "off") &
# Increase the top margin to account for 2pt padding I added for the tags
theme(
plot.margin = margin(t = 7.5, r = 5.5, b = 5.5, l = 5.5)
)