Add textbox to facet wrapped layout in ggplot2

笑着哭i 提交于 2019-12-17 18:41:11

问题


I am aware that one is able to annotate a plot created by ggplot2 or even to combine large and small viewports, as is documented in the ggplot2-book. However, it seems that these only work in the actual plot-areas and not in the "final plot".

For example I have a plot like this:

Here we see ten panels showing a linear regression smoother applied to a binomial dataset, but that´s not the point. Now I want a summary (stored in a dataframe) in form of a text in the lower right of the plot, such as this...

I did not find any example that comes even close. Any hints, helps or comments are much appreciated!


回答1:


Rather late to the game, but I haven't seen any solution that extends to multiple empty facet spaces, so here goes.

Step 0. Sample ggplot with 2 unfilled facets, using the inbuilt diamonds dataset:

library(ggplot2)

p <- ggplot(diamonds,
       aes(x = carat, y = price)) +
  geom_point() +
  geom_smooth() +
  facet_wrap(~color)
p

Step 1. Convert plot to gtable using ggplotGrob

gp <- ggplotGrob(p)

library(gtable)

# visual check of gp's layout (in this case, it has 21 rows, 15 columns)
gtable_show_layout(gp)

Step 2. (Optional) Get the cell coordinates of the unfilled cells to be used for textbox. You can skip this if you prefer to read off the layout above. In this case the top-left cell would be (16, 8) and the bottom-right cell would be (18, 12).

# get coordinates of empty panels to be blanked out
empty.area <- gtable_filter(gp, "panel", trim = F)
empty.area <- empty.area$layout[sapply(empty.area$grob,
                                       function(x){class(x)[[1]]=="zeroGrob"}),]

empty.area$t <- empty.area$t - 1 #extend up by 1 cell to cover facet header
empty.area$b <- empty.area$b + 1 #extend down by 1 cell to cover x-axis

> empty.area
   t  l  b  r z clip      name
6 16  8 18  8 1   on panel-3-2
9 16 12 18 12 1   on panel-3-3

Step 3. Overlay textbox as a tableGrob

library(gridExtra)

gp0 <- gtable_add_grob(x = gp,
                       grobs = tableGrob("some text",
                                         theme = ttheme_minimal()),
                       t = min(empty.area$t), #16 in this case
                       l = min(empty.area$l), #8
                       b = max(empty.area$b), #18
                       r = max(empty.area$r), #12
                       name = "textbox")
grid::grid.draw(gp0)

Demonstrating some variations:

gp1 <- gtable_add_grob(x = gp,
                       grobs = tableGrob("Simple line of comment that can go on & on for the sake of demonstration. Automatic line wrap not included.",
                                         theme = ttheme_minimal()),
                       t = min(empty.area$t),
                       l = min(empty.area$l),
                       b = max(empty.area$b),
                       r = max(empty.area$r),
                       name = "textbox")
grid::grid.draw(gp1)

gp2 <- gtable_add_grob(x = gp,
                       grobs = tableGrob("Simple line of comment that can go on & on. 
Automatic line wrap not included. \nAt least it understands the concept of line breaks.",
                                         theme = ttheme_minimal()),
                       t = min(empty.area$t),
                       l = min(empty.area$l),
                       b = max(empty.area$b),
                       r = max(empty.area$r),
                       name = "textbox")
grid::grid.draw(gp2)

gp3 <- gtable_add_grob(x = gp,
                       grobs = tableGrob(tibble::tribble(~col1, ~col2,
                                                         "a.", "This is a line in a table",
                                                         "b.", "This is another line in a table"),
                                         rows = NULL,
                                         theme = ttheme_minimal()),
                       t = min(empty.area$t),
                       l = min(empty.area$l),
                       b = max(empty.area$b),
                       r = max(empty.area$r),
                       name = "textbox")
grid::grid.draw(gp3)




回答2:


Since ggplot2 2.2, I've used the caption option instead. You might want to give that a try.

library(tidyverse)

ggplot(data = mtcars, 
            mapping = aes(y=mpg, x=wt)) +
  geom_point() +
  facet_wrap(c("gear", "cyl"), labeller = "label_both") +
  labs(title = "mtcars analysis",
       subtitle = "This is a subtitle \n",
       caption = "\n Note: This analysis compares the number of gears and cylinders", 
       x = "weight", y = "mpg")

And here's what you'd get:

I hope that helps you.



来源:https://stackoverflow.com/questions/28496764/add-textbox-to-facet-wrapped-layout-in-ggplot2

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