Converting corrplot output to grob

痞子三分冷 提交于 2021-01-28 03:27:40

问题


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!