Scransom
Scransom

Reputation: 3335

Annotate outside plot area once in ggplot with facets

I want to add an annotation outside the plotting area in a faceted ggplot. I can get the annotation that I want, but it's repeated for each facet. How can I get this annotation to appear only once?

E.g., to annotate "XX" once in the top left hand corner I can use:

library("ggplot2")
ggplot(mtcars, aes(x = hp, y = mpg)) +
  geom_point() +
  facet_grid(.~cyl ) + 
  annotate("text", x = -20, y = 36, label = "XX") +
  coord_cartesian(xlim = c(50, 350), ylim = c(10, 35), clip = "off")

annotated plot

However this actually annotates it to the top left of each facet.

How can I get this to only appear once?

Upvotes: 9

Views: 12555

Answers (4)

Valentin_Ștefan
Valentin_Ștefan

Reputation: 6426

Alternatively, the package cowplot has the handy annotation function draw_label(). When used in combination with ggdraw(), can annotate anywhere on the canvas/sheet with the coordinates ranging from 0 to 1 (relative to the entire canvas). The function cowplot::draw_label() uses ggplot2::annotation_custom() under the hood.

library(ggplot2)
library(cowplot)
#> Warning: package 'cowplot' was built under R version 3.5.2
#> 
#> Attaching package: 'cowplot'
#> The following object is masked from 'package:ggplot2':
#> 
#>     ggsave

# Revert to default theme; see https://stackoverflow.com/a/41096936/5193830
theme_set(theme_grey())

p <- ggplot(mtcars, aes(x = hp, y = mpg)) +
  geom_point() +
  facet_grid(. ~ cyl)

ggdraw(p) + draw_label("XX", x = 0.02, y = 0.97)

Created on 2019-01-14 by the reprex package (v0.2.1)

Upvotes: 3

user10614886
user10614886

Reputation: 21

With geom_text:

dummy <- data.frame(cyl = c(4), l = c("XX"), stringsAsFactors = F)

ggplot(mtcars, aes(x = hp, y = mpg)) +
  geom_point() +
  geom_text(data=dummy, aes(label=l), x = -20, y = 36) +
  facet_grid(.~cyl ) + 
  coord_cartesian(xlim = c(50, 350), ylim = c(10, 35), clip = "off")

enter image description here

Upvotes: 2

aosmith
aosmith

Reputation: 36076

You can put a single tag label on a graph using tag in labs().

ggplot(mtcars, aes(x = hp, y = mpg)) +
     geom_point() +
     facet_grid(.~cyl ) + 
     labs(tag = "XX") +
     coord_cartesian(xlim = c(50, 350), ylim = c(10, 35), clip = "off")

enter image description here

This defaults to "top left", though, which may not be what you want. You can move it around with the theme element plot.tag.position, either as coordinates (between 0 and 1 to be in plot space) or as a string like "topright".

ggplot(mtcars, aes(x = hp, y = mpg)) +
     geom_point() +
     facet_grid(.~cyl ) + 
     labs(tag = "XX") +
     coord_cartesian(xlim = c(50, 350), ylim = c(10, 35), clip = "off") +
     theme(plot.tag.position = c(.01, .95))

enter image description here

Upvotes: 12

Rui Barradas
Rui Barradas

Reputation: 76402

It's in fact very easy, just have a vector of labels, where the ones you don't want to plot are the empty string "".

library("ggplot2")

ggplot(mtcars, aes(x = hp, y = mpg)) +
  geom_point() +
  annotate("text", x = -20, y = 36, label = c("XX", "", "")) +
  facet_grid(.~cyl ) + 
  coord_cartesian(xlim = c(50, 350), ylim = c(10, 35), clip = "off")

enter image description here

Upvotes: 3

Related Questions