I need to combine the base graphics plot by the corrplot
package and plots made by ggplot2
graphics. These two graphics systems are incompatible in R, and I have found some workarounds to add them together in one panel, such as the patchwork
package or ggplotify
package. However, the case here is slightly different because these packages deal with one base plot at a time to convert it to a grob that can harmonize with any of ggplot2 graphs.
There is a special case where two base plots need to be added up in the viewport and then to be converted to the grob object of ggplot2. In this case, for example when you want to create a correlation matrix using the corrplot
package using the add = TRUE
parameter, which will simply draw a plot, and while you are viewing it you run the second code to add the second half matrix to get one full hybrid matrix as shown below using mtcars
data.
Hybrid correlation matrix by corrplot
library(tidyverse)
library(corrplot)
library(patchwork)
data(mtcars)
M32 <- cor(mtcars)
M21 <- cor(mtcars[-c(3, 8, 9, 18, 19, 20, 21, 26, 27, 28, 32), ]) # all 4 cylinders cars were removed in this data
corrplot::corrplot(M32, method = "color",
type = "lower",
order = "original",
hclust.method = "ward.D2",
col = COL2('PiYG'),
tl.pos = "lt",
is.corr = FALSE,
diag = TRUE,
tl.col = "black",
addrect = 2,
rect.col = "black",
addCoef.col = "white",
cl.cex = 0.8,
cl.align.text = 'l',
cl.pos = "b",
number.cex = 0.75
)
corrplot::corrplot(M21, method = "color",
type = "upper",
order = "original",
add = TRUE, # this argument is important to combine the two halves of the matrix
hclust.method = "ward.D2",
col = COL2('PiYG'),
tl.pos = "n",
is.corr = FALSE,
diag = TRUE,
tl.col = "black",
addrect = 2,
rect.col = "black",
addCoef.col = "white",
cl.cex = 0.8,
cl.align.text = 'l',
cl.pos = "n",
number.cex = 0.75
)
corHybridPlot <- recordPlot()
Very important, to get this hybrid matrix one should leave the first half of the matrix viewed and run the second part of the code for the second matrix to get one full matrix.
Sometimes, one needs to do dev.off()
to shut down any left-opened devices and start over again to get it to work.
Let's see the second plot by ggplot2 that I want to add to the first one.
Grpah by ggplot2
p1 <- ggplot(mtcars, aes(wt, mpg)) +
geom_point(color = "red") +
geom_text(aes(label = rownames(mtcars))) +
theme_classic(base_size = 16)
My Question
I think patchwork is very advanced and has many bells and whistles to meet publication-quality work. So, how to combine these two graphs in one panel using patchwork or any other method you see working?
I think the documentation for patchwork
is pretty clear. One easy option is to use the formula interface. For example, this works:
p1 + ~my_plot()
We could write your whole plot construction as a formula, but using a function is easier here. We just need to define my_plot
to do all the base plotting things you need:
my_plot <- function() {
M32 <- cor(mtcars)
M21 <- cor(mtcars[-c(3, 8, 9, 18, 19, 20, 21, 26, 27, 28, 32), ]) # all 4 cylinders cars were removed in this data
corrplot::corrplot(M32, method = "color",
type = "lower",
order = "original",
hclust.method = "ward.D2",
col = COL2('PiYG'),
tl.pos = "lt",
is.corr = FALSE,
diag = TRUE,
tl.col = "black",
addrect = 2,
rect.col = "black",
addCoef.col = "white",
cl.cex = 0.8,
cl.align.text = 'l',
cl.pos = "b",
number.cex = 0.75
)
corrplot::corrplot(M21, method = "color",
type = "upper",
order = "original",
add = TRUE, # this argument is important to combine the two halves of the matrix
hclust.method = "ward.D2",
col = COL2('PiYG'),
tl.pos = "n",
is.corr = FALSE,
diag = TRUE,
tl.col = "black",
addrect = 2,
rect.col = "black",
addCoef.col = "white",
cl.cex = 0.8,
cl.align.text = 'l',
cl.pos = "n",
number.cex = 0.75
)
}