0
votes

I am trying to make a plot that overlays two sets of data, both using geom_line and geom_point. Below is the data I'm working with.

library(ggplot2)
data <- structure(list(year = c("2017", "2017", "2018", "2018", "2019", "2019"), 
month = c("07", "07", "08", "08", "08", "08"),
day = c("04","04", "23", "23", "02", "02"), 
treatment = c("XH_ambient_air_1m", "XH_warmed_air_1m", "XH_ambient_air_1m", "XH_warmed_air_1m","XH_ambient_air_1m", "XH_warmed_air_1m"), 
average_temp = c(22.1354166666667,23.6472222222222, 19.0044444444444, 19.7804166666667,21.2144444444444,22.1973611111111), 
se_temp = c(0.730096702319543, 0.987515579446095,0.893437294439744, 0.852850129052693,1.29506347070289, 1.28123325200788), 
average_par = c(0.15899143259508, 0.163376534565775, 0.125768508018743,0.0725347340236767, 0.100666666666667, 0.0886666666666667), 
se_par = c(0.00664097819897585,0.0503344693576486, 0.0471636886635353, 0.0164506072528991,0.0364249609166266,0.0324054179283513)), 
row.names = c(NA, -6L), 
class = "data.frame")

Here is what I've done so far in ggplot. I've tried specifying group=treatment, but no lines show up when I run the code. I've also tried a group interaction between treatment and year, but that also didn't work.

ggplot(data, aes(x = month, color = treatment, shape = treatment)) +
  facet_grid(.~year) +
  geom_point(aes(y = average_temp)) +
  geom_point(aes(y = average_par * 100)) +
  geom_line(aes(y = average_temp, group = treatment)) +
  geom_line(aes(y = average_par * 100, group = treatment)) +
  scale_y_continuous(
    name = "Air Temperature (°C)",
    sec.axis = sec_axis(~./100, name="PAR")) + 
  theme_classic()

The first image is the output plot, and the second is my (badly) photoshopped version of how I would want it to look. The legend would also change in my photoshopped version, but I didn't want to spend forever fixing that.

Using R version 3.5.1, Mac OS X 10.13.6 attemptoutput

2
You can't draw lines between facets. If you want lines you will need a single x axis.Allan Cameron
I've seen people do this, but it tends to be pretty complicated. Like here. Search for something like "ggplot2 lines across facets".aosmith
@aosmith yes, it's possible, but it's a bad idea. It's possible to make this plot without faceting.Allan Cameron
@AllanCameron What would be your recommendation for recreating this plot without faceting?millie0725

2 Answers

2
votes

The way to get a very similar look without faceting would be something like this:

library(ggplot2)

data$date <- factor(paste(data$year, data$month, sep = "\n"),
                    levels = apply(expand.grid(unique(data$month),
                                               unique(data$year))[2:1], 
                                   1, paste, collapse = "\n"))
                    
ggplot(data, aes(x = date, color = treatment, shape = treatment)) +
  geom_point(aes(y = average_temp)) +
  geom_point(aes(y = average_par * 100)) +
  geom_line(aes(y = average_temp, group = treatment)) +
  geom_line(aes(y = average_par * 100, group = treatment)) +
  scale_y_continuous(name = "Air Temperature (\u00b0C)",
                     sec.axis = sec_axis(~./100, name="PAR")) + 
  scale_x_discrete(drop = FALSE, 
                   labels = rep(unique(data$month), length(unique(data$year)))) +
  geom_label(inherit.aes = FALSE,
             data = data.frame(x = 2 * 1:(length((levels(data$date)))/2) - 0.5, 
                               y = 1.1 * max(data$average_temp),
                               lab = paste("         ",
                                           sort(unique(data$year)),
                                           "         ")), 
             aes(x, y, label = lab)) +
  theme_classic() 

Created on 2020-07-24 by the reprex package (v0.3.0)

2
votes

Perhaps you are looking for this:

ym <- c(paste0(data$year,'_',data$month))
data1 <- data.frame(data,ym)

ggplot(data1, aes(x = ym, color = treatment, shape = treatment)) +
  #facet_grid(.~year) +
  geom_point(aes(y = average_temp)) +
  geom_point(aes(y = average_par * 100)) +
  geom_line(aes(y = average_temp, group = treatment)) +
  geom_line(aes(y = average_par * 100, group = treatment)) +
  scale_y_continuous(
    name = "Air Temperature (°C)",
    sec.axis = sec_axis(~./100, name="PAR")) + 
  theme_classic()+
  theme(legend.position="bottom")

gives this output:

output