问题
I am trying to use grid.arrange to combine multiple types of graph/table, one of which is a correlation matrix using corrplot
. Is there a way to convert a corrplot to a grob or export/import as an image compatible with grid.arrange
? Since the other plots I'm combining are from ggplot and tableGrob, I can't seem to use par(mfrow = c(2, 2))
or layout(matrix(1:2))
as suggested in other posts.
P1 <- corrplot(PANAcor, order="hclust", addgrid.col = "gray",
type="full", col = col2(50), tl.cex=1.5, tl.col="black",
method="color", tl.pos="lt", tl.srt=45, hclust.method = "average",
cl.ratio = 0.25, cl.align = "l", number.cex = 2)
summary <- grid.arrange(
top=textGrob(sprintf("%s Summary",subject), gp=gpar(fontsize=16,font=8)),
blank, P1, P2,
blank, T1, T2,
ncol=3, widths = c(0.1, 3, 3),
nrow=2, heights= c(1, 1),
bottom = textGrob(sprintf("%s run %s",version,runtime),
gp=gpar(fontsize=6,font=8), hjust=-1)
)
Error in gList(list(1, 0.45, 0.62, 0.55, 0.68, 0.64, -0.13, -0.37, -0.22, : only 'grobs' allowed in "gList" In addition: Warning message: In grob$wrapvp <- vp : Coercing LHS to a list
Data:
PANAcor <- structure(c(1, 0.56, 0.68, -0.49, -0.4, -0.39, 0.56, 1, 0.64, -0.55,
-0.49, -0.54, 0.68, 0.64, 1, -0.69, -0.57, -0.65, -0.49,
-0.55, -0.69, 1, 0.82, 0.73, -0.4, -0.49, -0.57, 0.82, 1,
0.71, -0.39, -0.54, -0.65, 0.73, 0.71, 1),
.Dim = c(6L, 6L),
.Dimnames = list(c("Anxious", "Irritable", "Upset", "Happy",
"Enthusiastic", "Outgoing"),
c("Anxious", "Irritable", "Upset", "Happy",
"Enthusiastic", "Outgoing")))
col2 <- colorRampPalette(c("#7bffff","#7bbdff","#0000ff","black",
"#ff1a1a","#ff8000","#ffff4d"))
回答1:
grid.echo
+ grid.grab
from the gridGraphics package will convert a graphic drawn by corrplot
into an identical-looking grob. Trouble is, the grob only looks identical at the exact same graphics device size.
Reproducing the problem:
library(gridGraphics)
library(grid)
corrplot(PANAcor, order="hclust", addgrid.col = "gray",
type="full", col = col2(50), tl.cex=1.5, tl.col="black",
method="color", tl.pos="lt", tl.srt=45, hclust.method = "average",
cl.ratio = 0.25, cl.align = "l", number.cex = 2)
## grab the scene as a grid object & save it to P1
grid.echo()
P1 <- grid.grab()
grid.draw(P1) # looks fine, until you resize the graphics device
Original size (looks identical to the graphic generated by corrplot
:
Larger size (coloured regions remain squares, even though the matrix has extended to rectangular cells, & don't extend to the edge of each cell):
Smaller size (coloured regions have a minimum height / width, which cause them to spill out beyond the confines of each cell):
And if we arrange multiple grobs together, it's almost certainly going to look weird:
library(gridExtra)
grid.arrange(P1, P1, P1, layout_matrix = matrix(c(1, 1, 2, 3), nrow = 2, ncol = 2))
In short, due to the way corrplot
draws the graphic, all other children grobs in P1 adjust in sync when the graphics device is re-sized, except for the grob responsible for colour.
Solution:
# save correlation matrix colors to a vector, then make coloured matrix grob transparent
matrix.colors <- getGrob(P1, gPath("square"), grep = TRUE)[["gp"]][["fill"]]
P1 <- editGrob(P1,
gPath("square"), grep = TRUE,
gp = gpar(col = NA,
fill = NA))
# apply the saved colours to the underlying matrix grob
P1 <- editGrob(P1,
gPath("symbols-rect-1"), grep = TRUE,
gp = gpar(fill = matrix.colors))
# convert the background fill from white to transparent, while we are at it
P1 <- editGrob(P1,
gPath("background"), grep = TRUE,
gp = gpar(fill = NA))
Replace gPath("square")
with gPath("circle")
if you use corrplot
's default method. I haven't tested the other method options for the corresponding grob names, but the general principle should be similar.
Check that everything's aligned now:
grid.arrange(P1, P1, P1, layout_matrix = matrix(c(1, 1, 2, 3), nrow = 2, ncol = 2))
By the way, you may want to adjust the text size arguments in corrplot
. Based on your current code, the labels appear rather large, and are liable to be cut off when you arrange multiple plots together.
来源:https://stackoverflow.com/questions/53734543/converting-corrplot-output-to-grob