Nick Pardikes
Nick Pardikes

Reputation: 3

How can I omit a particular section of a ggplot (geom_line) graph in R?

I am currently trying to plot results from an experiment in which I am comparing mortality rates between control and experimental treatments. The best presentation is to use geom_line to connect the mean values across each treatment (time delay). However, I would also like to include the control values to be able to show when mortality rates in experimental treatments return to similar values seen in the controls. I don't want geom_line() to draw a line from the control (w=0) to the first treatment (w=1). It's not very informative.

I tried to use subset within the geom_line() function. It works, but then the graph output is completely different compared to when I don't include the subset statement.

Here is some code that should help. This first script is to show you the normal plot

dat <- data.frame(w = c(rep(0, 4), rep(1, 4), rep(2, 4), rep(3, 4), rep(4, 4)), TempTr = c("24.C", "28.C", "24.NC", "28.NC"), Species = "S", Wasp = "A", mort = rnorm(20, 7, 1), se=rnorm(20, 0.5, 0.1))

pd = position_dodge(0.2)

dat %>%
  ggplot(aes(y=mort, x=w, colour=TempTr, group=TempTr)) + geom_errorbar(aes(ymin=mort-se, ymax=mort+se), colour="black", width=0, position = pd) + geom_point(aes(fill=TempTr), colour = "black", size=2, alpha=0.8, shape=21, position = pd) + geom_line(aes(linetype=TempTr), position=pd, size=1.25, alpha=0.8)

Now I try to remove the section between w=0 and w=1. In other words only show the lines from w=1:4

dat %>%
  ggplot(aes(y=mort, x=w, colour=TempTr, group=TempTr)) + geom_errorbar(aes(ymin=mort-se, ymax=mort+se), colour="black", width=0, position = pd) + geom_point(aes(fill=TempTr), colour = "black", size=2, alpha=0.8, shape=21, position = pd) + geom_line(aes(linetype=TempTr), position=pd, size=1.25, alpha=0.8, data=subset(dat, w %in% c("1", "2", "3", "4")))

This works, but it doesn't work with my real data. When I perform this with my real data (which has several species, thus several facets), the lines no longer connect the points correctly. The line between 0 and 1 is omitted, but the rest of the plot is wrong. Any idea why this is? Is it the order in which I put the functions? Normal plot from original data

Bad plot from original data after removing the desired section

Here are images from the original data.

Upvotes: 0

Views: 1309

Answers (1)

teofil
teofil

Reputation: 2384

In short, you need to group by the interaction between Species and TempTr.

To reproduce the problem we make a second dataset where Species is R. Then bind by row so we can facet by species later.

library(ggplot2)
library(dplyr)

dat <-
  data.frame(
    w = c(rep(0, 4), rep(1, 4), rep(2, 4), rep(3, 4), rep(4, 4)),
    TempTr = c("24.C", "28.C", "24.NC", "28.NC"),
    Species = "S",
    Wasp = "A",
    mort = rnorm(20, 7, 1),
    se = rnorm(20, 0.5, 0.1)
  )

dat2 <- dat %>% dplyr::mutate(Species="R")

dat3 <- dplyr::bind_rows(dat, dat2)

Then plot. Note the call to interaction in geom_line:

dat3 %>% ggplot(aes(
  y = mort,
  x = w,
  colour = TempTr,
  group = TempTr
)) + geom_errorbar(
  aes(ymin = mort - se, ymax = mort + se),
  colour = "black",
  width = 0,
  position = pd
) + geom_point(
  aes(fill = TempTr),
  colour = "black",
  size = 2,
  alpha = 0.8,
  shape = 21,
  position = pd
) + geom_line(
  aes(linetype = TempTr, 
# make sure the lines respect TempTr _and_ Species
  group=interaction(TempTr, Species)),
  position = pd,
  size = 1.25,
  alpha = 0.8,
  data = subset(dat3, w %in% c("1", "2", "3", "4"))
)+
  facet_wrap("Species")

Should make this:

enter image description here

EDIT: Facet by two variables. interaction in geom_line not needed

library(ggplot2)
library(dplyr)
# species S, wasp A
datSA <-
  data.frame(
    w = c(rep(0, 4), rep(1, 4), rep(2, 4), rep(3, 4), rep(4, 4)),
    TempTr = c("24.C", "28.C", "24.NC", "28.NC"),
    Species = "S",
    Wasp = "A",
    mort = rnorm(20, 7, 1),
    se = rnorm(20, 0.5, 0.1)
  )

# make other species:wasp combinations
datRA <- datSA %>% dplyr::mutate(Species="R")
datSB <- datSA %>% dplyr::mutate(Species="S", Wasp="B")
datRB <- datSA %>% dplyr::mutate(Species="R", Wasp="B")

# bind and make a variable for faceting
dat3 <- dplyr::bind_rows(datSA, datSB, datRA, datRB, .id="table") %>% 
  mutate(species_by_wasp=case_when(table == 1 ~ "SA",
                                   table == 2 ~ "SB",
                                   table == 3 ~ "RA",
                                   table == 4 ~ "RB"))

pd = position_dodge(0.2)

dat3 %>% ggplot(aes(
  y = mort,
  x = w,
  colour = TempTr,
  group = TempTr
)) + geom_errorbar(
  aes(ymin = mort - se, ymax = mort + se),
  colour = "black",
  width = 0,
  position = pd
) + geom_point(
  aes(fill = TempTr),
  colour = "black",
  size = 2,
  alpha = 0.8,
  shape = 21,
  position = pd
) + geom_line(
  aes(linetype = TempTr, group=TempTr),
  position = pd,
  size = 1.25,
  alpha = 0.8,
  data = subset(dat3, w %in% c("1", "2", "3", "4"))
)+
  # facet_grid(Species ~ Wasp)
  facet_wrap("species_by_wasp")

Should make this:

enter image description here

Upvotes: 3

Related Questions