Reputation: 556
I have the following data set:
structure(list(Jahr = 2005:2019, Fahrrad = c(275208L, 296105L,
308336L, 313363L, 326017L, 311756L, 302193L, 295702L, 268773L,
268295L, 256726L, 248916L, 250242L, 233652L, 230464L), E.Bike = c(1792L,
3181L, 5825L, 12600L, 23886L, 39247L, 49615L, 52941L, 49362L,
57613L, 66332L, 75665L, 87987L, 111661L, 133032L), gesamt = c(277000L,
299286L, 314161L, 325963L, 349903L, 351003L, 351808L, 348643L,
318135L, 325908L, 323058L, 324581L, 338229L, 345313L, 363496L
)), class = "data.frame", row.names = c(NA, -15L))
My goal is to create a graph that shows on the left y-axis the absolute purchases of different bike types. On the right y-axis id like to show the ratio of "E-Bike" purchases over "Fahrrad" purchases to emphasize the trend (if both are sold equally the desired value is 100, if e-bike is less than below 100). Something like this:
Is that even possible? I know ggplot doesn't allow some second y-axis.
Here is the code to produce the plot below (without the MS paint edits)
dfm <- melt(df, id="Jahr")
dfm$variable <- factor(dfm$variable, levels = c("gesamt", "Fahrrad", "E.Bike"))
dfm$variable <- revalue(dfm$variable, c("E.Bike"="E-Bike"))
dfm$value <- dfm$value/1000
ggplot(data=dfm) +
geom_line(aes(x=dfm$Jahr, y=dfm$value, colour=dfm$variable), lineend = "round", lwd=1.5)+
scale_x_continuous(limits = c(2013,2019), breaks = c(2013, 2014, 2015,2016, 2017,2018, 2019))+
scale_y_continuous(limits = c(0, 400))+
labs(title = "Verkäufe in Tausend")+
theme_minimal()+
scale_colour_manual(name="Mode",
labels=c("Total", "Fahrrad","E-Bike"),
values = c( "#8c8c8c", "#256bc2","#7ea9de"),
guide="none")+
geom_text(x = 2013.5, y = 350, label="Total" , hjust = "inward", size=3) +
geom_text(x = 2013.5, y = 290, label="Fahrrad" , hjust = "inward", size=3) +
geom_text(x = 2013.5, y = 80, label = "E-Bike", hjust = "inward", size=3)+
theme(legend.title = element_blank(),
axis.title.y=element_blank(),
axis.title.x=element_blank(),
panel.grid.minor.x=element_blank(),
panel.grid.major.x=element_blank(),
axis.text=element_text(size=8.5),
plot.title = element_text(hjust = -0.06, size=9),
plot.caption = element_text(hjust = -0.08, size=6,color="#BFBFBF"))
Upvotes: 3
Views: 4789
Reputation: 38053
The way that secondary axes work in ggplot are as follows. At the position scale, add a sec.axis
argument for a secondary axis that is a linear transformation of the first axis, specified in trans
. Since both the primary and secondary axes can start at 0, this means a simple scaling factor will do. You need to manually transform the input data and specify the reverse transformation as the trans
argument. Simplified example below (assuming df
is your provided data):
library(ggplot2)
library(scales)
dfm <- reshape2::melt(df, id="Jahr")
# Scale factor for utilising whole y-axis range
scalef <- max(df$gesamt) / max(df$E.Bike / df$gesamt)
# Scale factor for using 0-100%
# scalef <- max(df$gesamt)
ggplot(dfm, aes(Jahr, value)) +
geom_line(aes(colour = variable)) +
geom_line(aes(y = E.Bike / gesamt * scalef),
data = df, linetype = 2) +
scale_y_continuous(
labels = number_format(scale = 1e-3),
sec.axis = sec_axis(trans = ~ .x / scalef,
labels = percent_format(),
name = "Percentage E-bike")
)
Created on 2021-01-04 by the reprex package (v0.3.0)
Upvotes: 4