【问题标题】:How can I show a custom annotation only once on a faceted ggplot2?如何在多面 ggplot2 上仅显示一次自定义注释?
【发布时间】:2018-09-12 07:09:30
【问题描述】:

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

我可以使用annotation_custom 进行此操作,但注释出现了 6 次,每个方面一次。我想将它放在彩条索引下方一次。见下图。

我的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 给出了最接近的可能解决方案。下面给出了它的一个数字。 。添加的codeline是这样的。另外,这里要提一下,情节的边缘也被修剪了。

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")

【问题讨论】:

  • 我只需要一个注释方法,将整个情节作为一次而不是显示的 6 次。

标签: r ggplot2 heatmap


【解决方案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)

【讨论】:

  • 错误:找不到对象 egg。
【解决方案2】:

我不确定是否有办法使用自动生成的图例来实现您想要的。对问题的简要描述:要使其正常工作,必须有从一些 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)

【讨论】:

  • 上述解决方案的一个基本问题是该文本在每个方面图上重复了多次。如果 6 个地块是多面的。此文本 a,b,c... 在每个图上也重复 6 次。
猜你喜欢
  • 1970-01-01
  • 2010-11-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多