Gabrielle Macklin
Gabrielle Macklin

Reputation: 63

Two plots within one facet in ggplot2

I have two types of data to create two types of plot, bar and line. They have different y axis, but same x axis. They are each categorized by the same category levels

Example Code:

data <- data.frame( Station = sample(LETTERS[seq( from = 1, to = 4 )],50, rep = TRUE),
                  Date = sample(seq(as.Date('2015/01/01'), as.Date('2015/12/31'), by="day"), 50),
                   Presence = sample(0:10,50,rep = TRUE),
                   Noise = sample(70:130,50, rep=TRUE))
noise <-  ggplot()+
    geom_line(data = data,aes(x=Date, y= Noise, color= Station))+
    scale_x_date(date_breaks = "1 month")+
    facet_wrap(~Station, ncol=2, strip.position="right")+
    theme(axis.title.x = element_text(margin = margin(t = 20)))+
    guides(colour = guide_legend(override.aes = list(size=3)))+
    coord_cartesian(xlim = c(as.Date("2015-02-01"),as.Date("2015-10-30")))+
    labs( x='Date')+
    theme_classic(base_family = "serif")

enter image description here

pres <-ggplot()+
  geom_bar(data = data,aes(x= Date, y = Presence), stat = "identity")+
  scale_x_date(date_breaks = "1 month")+
  facet_wrap(~Station, ncol=2, strip.position="right")+
  theme(axis.title.x = element_text(margin = margin(t = 20)))+
  coord_cartesian(xlim = c(as.Date("2015-02-01"),as.Date("2015-10-30")))+
  labs( x='Date')+
  theme_classic(base_family = "serif")

enter image description here

What I would like to do, is to combine the two plots, but label with the same facet (Station).

Quick example I made in photoshop would look something like this:

enter image description here

etc.

Any help would be appreciated!

Upvotes: 1

Views: 1130

Answers (1)

koolmees
koolmees

Reputation: 2783

ggplot doesn't have a pretty way of doing this but it can certainly be done:

ggplot()+
  geom_line(data = data,aes(x=Date, y= Noise, color= Station))+
  geom_bar(data = data,aes(x= Date, y = Presence*10), stat = "identity")+
  scale_x_date(date_breaks = "1 month")+
  scale_y_continuous(
    name = "Noise",
    sec.axis = sec_axis(~./10, name="Presence")
  ) +
  facet_wrap(~Station, ncol=2, strip.position="right")+
  theme(axis.title.x = element_text(margin = margin(t = 20)))+
  guides(colour = guide_legend(override.aes = list(size=3)))+
  coord_cartesian(xlim = c(as.Date("2015-02-01"),as.Date("2015-10-30")))+
  labs( x='Date')+
  theme_classic(base_family = "serif")

So what is done here is adding the geom_bar after the geom_line and adding scale_y_continuous. The sec.axis in the latter provides a second axis however all the plots will be drawn on the primary axis regardless, the secondary axis has no functionality. In order to make proper use of it we need to define the scale bewteen the axes ourselves and add them to geom_bar and sec.axis.

The result looks as follows: enter image description here

You can also use the package ggbreak to create a break in the y-axis while both plots remain on the same y-axis like so:

ggplot()+
  geom_line(data = data,aes(x=Date, y= Noise, color= Station))+
  geom_bar(data = data,aes(x= Date, y = Presence), stat = "identity")+
  scale_x_date(date_breaks = "1 month")+
  scale_y_break(breaks = c(10, 70), scales = 1.5)+
  facet_wrap(~Station, ncol=4, strip.position="right")+
  theme(axis.title.x = element_text(margin = margin(t = 20)))+
  guides(colour = guide_legend(override.aes = list(size=3)))+
  coord_cartesian(xlim = c(as.Date("2015-02-01"),as.Date("2015-10-30")))+
  labs( x='Date')+
  theme_classic(base_family = "serif")

Which will look like so: enter image description here

I unfortunately wasn't able to make this work for ncol=2 as the order of the plots will mess up.

Upvotes: 1

Related Questions