Reputation: 25
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
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
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
Upvotes: 2