16

I'm trying to create a facet_wrap plot that compares four separate lines to a common fifth line; the goal is to have this fifth line appearing on all four of the other facet_wrap plots.

Here's my minimal code:

library(ggplot2)

x    = c( 1,  3,  1,  3,  2,  4,  2,  4)
y    = c( 1,  3,  2,  4,  1,  3,  2,  4)
type = c("A","A","B","B","C","C","D","D")
data = data.frame(x,y,type)

x    = c( 4,  1)
y    = c( 1,  4)
type = c("E","E")
line = data.frame(x,y,type)

ggplot(data, aes(x,y)) + geom_line() + facet_wrap(~type) +
geom_line(data = line, aes(x,y))

I was hoping that adding the fifth line as an independent data.frame would allow me to do this, but it just adds it as a fifth facet, as in the following image:

Bad facet plot

I want the "E" facet to show up on all of the other plots. Any thoughts? I know that geom_vline, geom_hline, and geom_abline will all appear on all of the facets, but I'm not sure what makes them unique.

hfisch
  • 1,312
  • 4
  • 19
  • 36

2 Answers2

10

You have specified type='E' in your line data.frame. If you want to have this line on type A,B,C,D, then create a data.frame with the types on which you want the line to display

xl    = c( 4,  1)
yl    = c( 1,  4)
type =rep(LETTERS[1:4], each=2)
line2 = data.frame(x=xl,y=yl,type)

ggplot(data, aes(x,y)) + geom_line() + facet_wrap(~type) +
   geom_line(data = line2)

You could also use annotate, which means you don't specify a data.frame, but pass the x and y values directly

ggplot(data, aes(x,y)) + geom_line() + facet_wrap(~type) +
  annotate(geom='line', x=xl,y=yl)

Both create

enter image description here

dfrankow
  • 20,191
  • 41
  • 152
  • 214
mnel
  • 113,303
  • 27
  • 265
  • 254
  • 1
    You may even omit the type column completely, i.e. `line2 = data.frame(x=xl,y=yl)`. The line will be the same across all panels then... – Mark Heckmann Nov 12 '15 at 08:40
  • I have this same problem, but this solution no longer works: "Error: You're passing a function as global data. Have you misspelled the `data` argument in `ggplot()`" – Adrian Martin Mar 06 '20 at 20:40
  • This still works for me, so @AdrianMartin must have stumbled upon some other issues when he could not make it work. – madsR May 27 '21 at 16:40
5

You could also use geom_abline(...) as follows:

x    <-  c( 1,  3,  1,  3,  2,  4,  2,  4)
y    <-  c( 1,  3,  2,  4,  1,  3,  2,  4)
type <-  c("A","A","B","B","C","C","D","D")
data <-  data.frame(x,y,type)

int   <- c(5,5,5,5)
slope <- c(-1,-1,-1,-1)
type  <- c("A","B","C","D")
ref   <- data.frame(int, slope, type)
ggplot(data, aes(x,y)) + geom_line() + facet_wrap(~type, scales="free") +
  geom_abline(data = ref, aes(intercept=int, slope=slope), color="red", size=2)

Which produces this:

jlhoward
  • 58,004
  • 7
  • 97
  • 140
  • I might have made my reproducible example a bit too simple; my actual code actually has more than just two points. I should have added a third point to illustrate my problem. Regardless, your answer definitely solves the question as I submitted it. – hfisch Dec 05 '13 at 00:28