Stacy
Stacy

Reputation: 25

Plotting with secondary axis

I am trying to overlay a bar graph (primary axis) and line (secondary axis), but I keep getting an error that I don't understand how to fix. I have tried to follow multiple examples from other questions, but I'm still not getting the result I need.

Here's my code:

ggplot(data = MRIP, aes(x = Length_mm)) +
    geom_bar(aes(y = Perc.of.Fish), stat="identity", width = 10, fill = "black") + 
    geom_line(aes(y = Landings), stat = "identity", size = 2, color = "red") +
    scale_y_continuous(name = "Percentage", sec.axis = sec_axis (~./Landings, name = "Landings")) 

How do I fix this error: "Error in f(...) : object 'Landings' not found"?

Upvotes: 0

Views: 86

Answers (1)

Limey
Limey

Reputation: 12461

Try this:

coef <- 4000
MRIP %>% 
    mutate(LandingsPlot=Landings/coef) %>% 
    ggplot(aes(x = Length_mm)) +
    geom_col(aes(y = Perc.of.Fish), width = 10, fill = "black") + 
    geom_line(aes(y = LandingsPlot), size = 2, color = "red") +
    scale_y_continuous(
      name = "Percentage", 
      sec.axis = sec_axis (trans= ~.*coef, name = "Landings")
    ) 

Giving

modified plot

Why does this work? The scale factor used to define the secondary axis cannot be part of the input data.frame - because if it were, it could potentially vary across rows (as it does here). That would mean you had a separate scale for each row of the input data.frame. That doesn't make sense. So, you scale the secondary variable to take a similar range to that of the primary variable. I chose coef <- 4000 by eye. The exact value doesn't matter, so long as it's sensible.

Having divided by the scale factor to obtain the plotted values, you need to multiply by the scale factor in the transformation in order to get the correct labels on the secondary axis.

Thank you for providing a good MWE. But next time, for extra marks, please post the results of dput() in your question rather than in the comments...

Update To answer OP's follow up question in the comments: legends are linked to aesthetics. So to get a legend, move the attribute that you want to label inside aes(). You can then define and customise the legend using the appropriate scale_<aesthetic>_<type>. However it's worth noting that if you write, say, aes(colour="black") then "black" is just a character string. It doesn't define a colour. (Using the standard defaults, it will in fact appear as a slightly pinkish red, labelled "black"!) This can be confusing, so it might be a good idea to use arbitrary strings like "a", "b" and "c" (or "Landings" and "Percentage") in the aesthetics. Anyway...

coef <- 4000
#Note fill and color have moved inside aes()
MRIP %>% 
  mutate(LandingsPlot=Landings/coef) %>% 
  ggplot(aes(x = Length_mm)) +
  geom_col(aes(y = Perc.of.Fish, fill = "black"), width = 10,) + 
  geom_line(aes(y = LandingsPlot, color = "red"), size = 2) +
  scale_y_continuous(
    name = "Percentage", 
    sec.axis = sec_axis (trans= ~.*coef, name = "Landings")
  ) +
  scale_color_manual(values=c("red"), labels=c("Landings"), name=" ") +
  scale_fill_manual(values=c("black"), labels=c("Percentage"), name=" ")

Gives

enter image description here

Upvotes: 2

Related Questions