The cowplot package provides functions to draw with and on plots. These functions enable us to take plots and add arbitrary annotations or backgrounds, to place plots inside of other plots, to arrange plots in more complicated layouts, or to combine plots from different graphic systems (ggplot2, grid, lattice, base). This functionality is build on top of ggplot2, i.e., the resulting plots are ggplot2 objects and they can be modified, extended, and outputted just like regular ggplot2 plots.
We start with some simple annotations, such as labels or watermarks. Let’s begin with a basic plot of the
Next we’re going to watermark this plot with the word “Draft”. To do so, we wrap the plot into a drawing environment via the
ggdraw() call, and then add annotations via various
ggdraw(p) does is it captures a snapshot of the plot, so that the plot effectively turns into an image, and then it draws that image into a new ggplot2 canvas without visible axes or background grid. The
draw_* functions are simply wrappers around regular geoms. So, in the above example we could have used
geom_text() instead of
However, notice how much more verbose the call to
geom_text() is. Also,
geom_text() interprets font sizes in mm, so we need to divide by
.pt if we want to specify font sizes in the more conventional point metric. By contrast,
draw_label() performs this conversion for us, so we can specify font sizes directly in points.
We can also save the annotated plots in the standard way via
(However, the cowplot package provides an alternative to
ggsave(), the function
save_plot(), which makes it easier to save plots with appropriate sizing, in particular when making compound plots. See the documentation of
save_plot() for details.)
Frequently, we may want to have the annotations underneath the plot rather than on top of it. We can achieve this effect by first setting up an empty drawing layer with
ggdraw(), then adding the label, and then adding the plot with
This requires that the plot has a transparent background, and all cowplot themes meet this requirement. By contrast, this is not necessarily the case for ggplot2 themes. For example, if we change the theme of the plot to
theme_classic() the underlying label is hidden by the theme’s white background.
The cowplot theme
theme_half_open() does not have this limitation.
draw_plot() function also allows us to place plots at arbitrary locations and at arbitrary sizes onto the canvas. This is useful for combining subplots into a layout that is not a simple grid, e.g. with an inset plotted inside a larger graph.
This feature is not limited to ggplot2 plots. It works with base graphics as well.
By default, the coordinate system used by
ggdraw() uses relative coordinates running from 0 to 1 for both x and y. Sometimes, however, we need to be able to place graphical elements at absolute units, e.g. exactly 1 inch from the left border. We can do so via the grid graphic system, which is supported through the
draw_grob() function. For example, the following code generates a blue square of 1 inch width and height that is located exactly 1 inch from the left and 1 inch from the top border of the plot area.
If we regenerate the plot in a different size, the blue square remains at the same absolute position and retains its absolute size.
The drawing layer also supports images, through the function
draw_image(). This function, which requires the magick package to be installed, can take images in many different formats and combine them with plots. For example, we can use an image as a plot background:
library(magick) library(dplyr) library(forcats) img <- system.file("extdata", "cow.jpg", package = "cowplot") %>% image_read() %>% image_resize("570x380") %>% image_colorize(35, "white") p <- PASWR::Cows %>% filter(breed != "Canadian") %>% mutate(breed = fct_reorder(breed, butterfat)) %>% ggplot(aes(butterfat, fill = breed)) + geom_density(alpha = 0.7) + scale_fill_grey() + coord_cartesian(expand = FALSE) + theme_minimal_hgrid(11, color = "grey30") ggdraw() + draw_image(img) + draw_plot(p)
We can also add an image as a logo onto a plot.