如何在多面ggplot2上仅显示一次自定义注释?

时间:2018-09-12 07:09:31

标签: r ggplot2 heatmap

Please see this

我在ggplot2中制作了一个多面图(请参见上图),我想添加一个额外的图例以表示除图的X轴和Y轴之外我还使用了字母索引显示的颜色图例。

我能够使用annotation_custom进行此操作,但是注释出现了6次,每个面一次。我想将其放置在颜色栏索引下方一次。参见下图。Multiple times the legend appears.

我的ggplot2代码如下所示

library(ggplot2)
corrma <- ggplot(samelt, aes(x = Var1, y = Var2, fill = value)) +
  geom_tile(color = "white") +
  scale_fill_gradient2(low = "steelblue", high = "tomato2", 
                       mid = "white",  
                       midpoint = 0,
                       limit = c(-1,1)) +
  theme_minimal() +
  scale_y_discrete(labels = s3) +
  scale_x_discrete(labels = s3) +
  coord_fixed() +
  facet_wrap( ~ Country, nrow = 2) +
  labs(title = "Correlation Matrix of South Asian Indicators") +
  theme(legend.direction = "horizontal")+
  theme(plot.margin = unit(c(0,0,0,0), "cm")) 

text <- paste(  "a - Age_dpdn_ratio_wkpop\n",
                "b - Birth_rt\n",
                "c - Death_rt\n",
                "d - Fertility_rt\n",
                "e - Health_exp_pcofGDP\n",
                "f - Life_exp\n",
                "g - Private_hlth_exp_pc_oftotal\n",
                "h - ruralpop_drnkwater_pc", sep = " ")

text.p <- ggparagraph(text = text, face = "italic", size = 8, color = "black")

corrma + annotation_custom(ggplotGrob(text.p))

经过几次试验,我发现cowplot提供了最接近的解决方案。如下图所示。 THIS。添加的代码行是这样的。另外,在这里要提到的是,地块的边距也已被修剪。

library(cowplot)
plot_grid(corma, text.p, nrow = 2, ncol=1, align= "v", axis = "l", rel_widths = c(1, .1), rel_heights = c(1, .1))

我想这只能是临时解决方法。

structure(list(Var1 = structure(c(1L, 2L, 3L, 4L, 5L, 6L, 7L, 
8L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 3L, 4L, 5L, 6L, 7L, 8L, 4L, 5L, 
6L, 7L, 8L, 5L, 6L, 7L, 8L, 6L, 7L, 8L, 7L, 8L, 8L, 1L, 2L, 3L, 
4L, 5L, 6L, 7L, 8L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 3L, 4L, 5L, 6L, 
7L, 8L, 4L, 5L, 6L, 7L, 8L, 5L, 6L, 7L, 8L, 6L, 7L, 8L, 7L, 8L, 
8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 
3L, 4L, 5L, 6L, 7L, 8L, 4L, 5L, 6L, 7L, 8L, 5L, 6L, 7L, 8L, 6L, 
7L, 8L, 7L, 8L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 2L, 3L, 4L, 
5L, 6L, 7L, 8L, 3L, 4L, 5L, 6L, 7L, 8L, 4L, 5L, 6L, 7L, 8L, 5L, 
6L, 7L, 8L, 6L, 7L, 8L, 7L, 8L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 
8L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 3L, 4L, 5L, 6L, 7L, 8L, 4L, 5L, 
6L, 7L, 8L, 5L, 6L, 7L, 8L, 6L, 7L, 8L, 7L, 8L, 8L, 1L, 2L, 3L, 
4L, 5L, 6L, 7L, 8L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 3L, 4L, 5L, 6L, 
7L, 8L, 4L, 5L, 6L, 7L, 8L, 5L, 6L, 7L, 8L, 6L, 7L, 8L, 7L, 8L, 
8L), .Label = c("ruralpop_drnkwater_pc", "Life_exp", "Fertility_rt", 
"Private_hlth_exp_pc_oftotal", "Death_rt", "Health_exp_pcofGDP", 
"Birth_rt", "Age_dpdn_ratio_wkpop"), class = "factor"), Var2 = structure(c(1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 3L, 3L, 
3L, 3L, 3L, 3L, 4L, 4L, 4L, 4L, 4L, 5L, 5L, 5L, 5L, 6L, 6L, 6L, 
7L, 7L, 8L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 3L, 3L, 3L, 3L, 3L, 3L, 4L, 4L, 4L, 4L, 4L, 5L, 5L, 5L, 
5L, 6L, 6L, 6L, 7L, 7L, 8L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L, 3L, 3L, 4L, 4L, 4L, 4L, 
4L, 5L, 5L, 5L, 5L, 6L, 6L, 6L, 7L, 7L, 8L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L, 3L, 3L, 
4L, 4L, 4L, 4L, 4L, 5L, 5L, 5L, 5L, 6L, 6L, 6L, 7L, 7L, 8L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 3L, 3L, 
3L, 3L, 3L, 3L, 4L, 4L, 4L, 4L, 4L, 5L, 5L, 5L, 5L, 6L, 6L, 6L, 
7L, 7L, 8L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 3L, 3L, 3L, 3L, 3L, 3L, 4L, 4L, 4L, 4L, 4L, 5L, 5L, 5L, 
5L, 6L, 6L, 6L, 7L, 7L, 8L), .Label = c("ruralpop_drnkwater_pc", 
"Life_exp", "Fertility_rt", "Private_hlth_exp_pc_oftotal", "Death_rt", 
"Health_exp_pcofGDP", "Birth_rt", "Age_dpdn_ratio_wkpop"), class = "factor"), 
    value = c(1, 1, -1, -0.79, -1, -0.98, -1, -1, 1, -1, -0.79, 
    -1, -0.98, -1, -1, 1, 0.8, 1, 0.98, 1, 1, 1, 0.76, 0.77, 
    0.82, 0.78, 1, 0.98, 1, 1, 1, 0.97, 0.98, 1, 1, 1, 1, 1, 
    -0.98, 0.63, -1, -0.48, -0.82, -0.99, 1, -0.97, 0.59, -0.99, 
    -0.53, -0.8, -0.98, 1, -0.7, 0.99, 0.38, 0.92, 0.99, 1, -0.64, 
    0.21, -0.72, -0.73, 1, 0.47, 0.87, 0.99, 1, 0.17, 0.36, 1, 
    0.89, 1, 1, 1, -0.99, 0.87, -0.99, 0.56, -1, -1, 1, -1, 0.88, 
    -1, 0.56, -1, -1, 1, -0.89, 1, -0.55, 1, 1, 1, -0.89, 0.37, 
    -0.88, -0.88, 1, -0.56, 1, 1, 1, -0.55, -0.58, 1, 1, 1, 1, 
    1, -1, 0.58, -0.98, 0.64, -1, -0.98, 1, -1, 0.54, -1, 0.62, 
    -1, -0.95, 1, -0.57, 0.99, -0.63, 1, 0.97, 1, -0.48, 0.41, 
    -0.58, -0.68, 1, -0.6, 0.99, 0.92, 1, -0.64, -0.67, 1, 0.97, 
    1, 1, 0.99, -0.99, 0.74, -0.97, -0.89, -0.99, -0.99, 1, -1, 
    0.79, -0.99, -0.91, -1, -1, 1, -0.8, 0.99, 0.91, 1, 1, 1, 
    -0.84, -0.77, -0.8, -0.82, 1, 0.92, 0.99, 1, 1, 0.91, 0.91, 
    1, 1, 1, 1, 0.93, -0.52, 0.89, -0.47, -0.9, -0.78, 0.02, 
    1, -0.18, 0.69, -0.77, -0.76, -0.5, -0.34, 1, -0.71, -0.44, 
    0.7, 0.94, -0.79, 1, -0.1, -0.82, -0.89, 0.29, 1, 0.25, -0.14, 
    0.84, 1, 0.87, -0.24, 1, -0.59, 1), Country = c("India", 
    "India", "India", "India", "India", "India", "India", "India", 
    "India", "India", "India", "India", "India", "India", "India", 
    "India", "India", "India", "India", "India", "India", "India", 
    "India", "India", "India", "India", "India", "India", "India", 
    "India", "India", "India", "India", "India", "India", "India", 
    "Pakistan", "Pakistan", "Pakistan", "Pakistan", "Pakistan", 
    "Pakistan", "Pakistan", "Pakistan", "Pakistan", "Pakistan", 
    "Pakistan", "Pakistan", "Pakistan", "Pakistan", "Pakistan", 
    "Pakistan", "Pakistan", "Pakistan", "Pakistan", "Pakistan", 
    "Pakistan", "Pakistan", "Pakistan", "Pakistan", "Pakistan", 
    "Pakistan", "Pakistan", "Pakistan", "Pakistan", "Pakistan", 
    "Pakistan", "Pakistan", "Pakistan", "Pakistan", "Pakistan", 
    "Pakistan", "Bangladesh", "Bangladesh", "Bangladesh", "Bangladesh", 
    "Bangladesh", "Bangladesh", "Bangladesh", "Bangladesh", "Bangladesh", 
    "Bangladesh", "Bangladesh", "Bangladesh", "Bangladesh", "Bangladesh", 
    "Bangladesh", "Bangladesh", "Bangladesh", "Bangladesh", "Bangladesh", 
    "Bangladesh", "Bangladesh", "Bangladesh", "Bangladesh", "Bangladesh", 
    "Bangladesh", "Bangladesh", "Bangladesh", "Bangladesh", "Bangladesh", 
    "Bangladesh", "Bangladesh", "Bangladesh", "Bangladesh", "Bangladesh", 
    "Bangladesh", "Bangladesh", "Nepal", "Nepal", "Nepal", "Nepal", 
    "Nepal", "Nepal", "Nepal", "Nepal", "Nepal", "Nepal", "Nepal", 
    "Nepal", "Nepal", "Nepal", "Nepal", "Nepal", "Nepal", "Nepal", 
    "Nepal", "Nepal", "Nepal", "Nepal", "Nepal", "Nepal", "Nepal", 
    "Nepal", "Nepal", "Nepal", "Nepal", "Nepal", "Nepal", "Nepal", 
    "Nepal", "Nepal", "Nepal", "Nepal", "Bhutan", "Bhutan", "Bhutan", 
    "Bhutan", "Bhutan", "Bhutan", "Bhutan", "Bhutan", "Bhutan", 
    "Bhutan", "Bhutan", "Bhutan", "Bhutan", "Bhutan", "Bhutan", 
    "Bhutan", "Bhutan", "Bhutan", "Bhutan", "Bhutan", "Bhutan", 
    "Bhutan", "Bhutan", "Bhutan", "Bhutan", "Bhutan", "Bhutan", 
    "Bhutan", "Bhutan", "Bhutan", "Bhutan", "Bhutan", "Bhutan", 
    "Bhutan", "Bhutan", "Bhutan", "Sri Lanka", "Sri Lanka", "Sri Lanka", 
    "Sri Lanka", "Sri Lanka", "Sri Lanka", "Sri Lanka", "Sri Lanka", 
    "Sri Lanka", "Sri Lanka", "Sri Lanka", "Sri Lanka", "Sri Lanka", 
    "Sri Lanka", "Sri Lanka", "Sri Lanka", "Sri Lanka", "Sri Lanka", 
    "Sri Lanka", "Sri Lanka", "Sri Lanka", "Sri Lanka", "Sri Lanka", 
    "Sri Lanka", "Sri Lanka", "Sri Lanka", "Sri Lanka", "Sri Lanka", 
    "Sri Lanka", "Sri Lanka", "Sri Lanka", "Sri Lanka", "Sri Lanka", 
    "Sri Lanka", "Sri Lanka", "Sri Lanka")), .Names = c("Var1", 
"Var2", "value", "Country"), row.names = c("1", "2", "3", "4", 
"5", "6", "7", "8", "10", "11", "12", "13", "14", "15", "16", 
"19", "20", "21", "22", "23", "24", "28", "29", "30", "31", "32", 
"37", "38", "39", "40", "46", "47", "48", "55", "56", "64", "17", 
"25", "33", "41", "51", "61", "71", "81", "101", "111", "121", 
"131", "141", "151", "161", "191", "201", "211", "221", "231", 
"241", "281", "291", "301", "311", "321", "371", "381", "391", 
"401", "461", "471", "481", "551", "561", "641", "18", "26", 
"34", "42", "52", "62", "72", "82", "102", "112", "122", "132", 
"142", "152", "162", "192", "202", "212", "222", "232", "242", 
"282", "292", "302", "312", "322", "372", "382", "392", "402", 
"462", "472", "482", "552", "562", "642", "110", "27", "35", 
"43", "53", "63", "73", "83", "103", "113", "123", "133", "143", 
"153", "163", "193", "203", "213", "223", "233", "243", "283", 
"293", "303", "313", "323", "373", "383", "393", "403", "463", 
"473", "483", "553", "563", "643", "114", "210", "36", "44", 
"54", "65", "74", "84", "104", "115", "124", "134", "144", "154", 
"164", "194", "204", "214", "224", "234", "244", "284", "294", 
"304", "314", "324", "374", "384", "394", "404", "464", "474", 
"484", "554", "564", "644", "116", "215", "310", "45", "57", 
"66", "75", "85", "105", "117", "125", "135", "145", "155", "165", 
"195", "205", "216", "225", "235", "245", "285", "295", "305", 
"315", "325", "375", "385", "395", "405", "465", "475", "485", 
"555", "565", "645"), class = "data.frame")

2 个答案:

答案 0 :(得分:1)

您可以尝试egg::geom_custom()

d <- data.frame(vs = 1, x=30, y=300)
d$grob <- list(grid::textGrob('test'))
ggplot(mtcars, aes(mpg,disp)) + facet_wrap(~vs) + geom_point() +
  egg::geom_custom(data = d, aes(x,y,data=grob), grob_fun = identity,
                   inherit.aes = F)

答案 1 :(得分:0)

我不确定是否可以使用自动生成的图例来实现所需的功能。问题的简要说明:为使此方法起作用,必须从某些geom_*到数据中的值的映射,而您的示例不是这种情况。

也许有一种更优雅的方法可以做到这一点,但这是一个将ggplotGrob()annotation_custom()grid::grid.draw()一起使用的示例:

这里的想法是在ggplot2中放置一个称为 grob 的外来图形元素(在本例中为注释)。由于您未提供任何数据,因此我在下面的示例中使用了mpg数据集中的数字列。请注意,我已经稍微修改了您的代码(颜色渐变图例的合理性):

# long format of the numeric columns in `mpg`
d <- cor(mpg %> % select_if(is.numeric)) %> % reshape2::melt()

# axis labels
s3 <- c("a", "b", "c", "d", "e")

# legend keys
labs <- c("a - engine displacement\nb - year of manufacture\nc - number of cylinders\nd - city miles per gallon\ne - highway miles per gallon")

p <- ggplot(data = d) +
     geom_tile(aes(x = Var1, y = Var2, fill = value), color = "white") +
     scale_fill_gradient2(low = "steelblue", high = "tomato2",
        mid = "white",
        midpoint = 0,
        limit = c(-1, 1)) +
     theme_minimal() +
     scale_y_discrete(labels = s3) +
     scale_x_discrete(labels = s3) +
     theme(legend.direction = "horizontal", legend.justification = "top") +
     labs(fill = "Pearson\nCoefficient")

通过追加添加注释

+ annotation_custom(textGrob(label = labs, just = "left",
                           gp = gpar(fontsize = 11)), 
                  ymin = 1, ymax = 4, xmin = 6.5)

以上。接下来,生成ggplot2 grob,关闭裁剪并绘制结果。

g <- ggplotGrob(p)
g$layout$clip[g$layout$name == "panel"] <- "off"
grid::grid.draw(g)

enter image description here