r - 向 ggplot 添加第二个 y 轴
问题描述
我有以下数据集:
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))
我的目标是创建一个图表,在左侧 y 轴上显示不同自行车类型的绝对购买量。在右侧的 y 轴 id 上显示“E-Bike”购买量与“Fahrrad”购买量的比率,以强调趋势(如果两者的销售量相同,则期望值为 100,如果电动自行车低于 100) . 像这样的东西:
这甚至可能吗?我知道 ggplot 不允许第二个 y 轴。
这是生成下面的图的代码(没有 MS 油漆编辑)
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"))
解决方案
ggplot 中辅助轴的工作方式如下。在位置刻度处,sec.axis
为第二个轴添加一个参数,该轴是第一个轴的线性变换,在 中指定trans
。由于主轴和次轴都可以从 0 开始,这意味着一个简单的比例因子就可以了。您需要手动转换输入数据并将反向转换指定为trans
参数。下面的简化示例(假设df
是您提供的数据):
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")
)
由reprex 包(v0.3.0)于 2021-01-04 创建
推荐阅读
- php - Laravel:从表用户获取名称
- django - django view - 用户通过测试多个条件?
- python - pandas astype 无法识别固定长度的字节串格式
- python - 用于保存球面点数据的快速 Python 代码
- node.js - 如何为 Sequelize 模型中的特定列设置排序规则?
- c++ - SFINAE 拒绝 GCC8.2 上的类型失败,GCC7.1 可以
- python-3.x - 为什么我不能减少 urllib.parse.urljoin?
- ms-access - 为什么对 MS Access 列表框或组合框进行重新查询会两次调用数据库?
- angular - 自动填充角度材质 从 URL 中选择选项
- javascript - 如何在 Google 应用制作工具中创建此字符计数器?