这个问题已经得到解答,但将次要轴和辅助比例尺添加到ggplot对象的右侧是一个常见的问题。我想在下面报告一下自己对此问题的微调,基于本主题中以及其他几个主题中给出的各种答案的几个元素(请参阅以下参考文献的部分清单),因为我需要大量生成双Y轴图,所以我编写了一个功能
ggplot_dual_axis()
。以下是可能感兴趣的特点:
1. 代码显示左y轴和右y轴的网格线(虽然这很简单,但这是我做出的主要贡献)
2. 代码打印并嵌入欧元符号到pdf中(我在这里看到的东西:
Plotting Euro Symbol € in ggplot2?)
3. 代码试图避免重复打印某些元素(“尝试”意味着我对其完全成功表示怀疑)
未回答的问题:
1. 是否有一种方法可以修改
ggplot_dual_axis()
函数,以便在没有geom元素的情况下删除其中一个
geom_line()
或
geom_point()
等而不会引发错误。伪代码类似于
if has(geom_line) ...
2. 如何通过关键字而不是索引调用
g2$grobs[[7]]
?这就是它返回的内容:
text[axis.title.y.text.232]
我对该问题的兴趣源于尝试通过应用类似技巧来捕获网格线而失败。我认为网格线在
g2$grobs[[4]]
中的某个地方隐藏,但我不确定如何访问它们。
编辑。我自己回答的问题:如何增加右侧的图表边距,其中“欧元”标签位于此处?答案是:
theme(plot.margin = unit(c(1,3,0.5,0.8), "lines"))
,例如,将起到作用。
请指出任何明显的问题或建议改进。现在看一下代码:希望对某人有用。正如我所说的,我不声称原创性,它是其他人已经显示的东西的组合。
ggplot_dual_axis <- function(lhs, rhs, axis.title.y.rhs = "rotate") {
rhs <- rhs + theme(axis.text.y = element_text(hjust = 0))
if (missing(axis.title.y.rhs) |
axis.title.y.rhs %in% c("rotate", "rotated")) {
rhs <- rhs + theme(axis.title.y = element_text(angle = 270))
}
lhs <- lhs + theme(panel.grid.minor = element_blank())
rhs <- rhs + theme(panel.grid.minor = element_blank(),
panel.background = element_rect(fill = "transparent", colour = NA),
plot.background = element_rect(fill = "transparent", colour = NA))
library("gtable")
g1 <- ggplot_gtable(ggplot_build(lhs))
g2 <- ggplot_gtable(ggplot_build(rhs))
pp <- c(subset(g1$layout, name == "panel", se = t:r))
g <- gtable_add_grob(g1,
g2$grobs[[which(g2$layout$name == "panel")]], pp$t, pp$l, pp$b, pp$l)
ia <- which(g2$layout$name == "axis-l")
ga <- g2$grobs[[ia]]
ax <- ga$children[["axis"]]
ax$widths <- rev(ax$widths)
ax$grobs <- rev(ax$grobs)
ax$grobs[[1]]$x <- ax$grobs[[1]]$x - unit(1, "npc") + unit(0.15, "cm")
g <- gtable_add_cols(g, g2$widths[g2$layout[ia, ]$l], length(g$widths) - 1)
g <- gtable_add_grob(g, ax, pp$t, length(g$widths) - 1, pp$b)
g <- gtable_add_grob(g, g2$grobs[[7]], pp$t, length(g$widths), pp$b)
library("gridExtra")
grid.newpage()
return(arrangeGrob(g))
}
以下是一些虚假数据和两个图表,这些图表的单位是美元和欧元。如果有一个包可以让您制作一个图表并将其包裹在一个双y轴图中,那不是很酷吗?例如:ggplot_dual_axis_er(ggplot_object, currency = c("dollar", "euro"))
,它会自动为您获取汇率! :-)
if(.Platform$OS.type == "windows"){
setwd("c:/R/plots")
} else {
setwd("~/R/plots")
}
library("ggplot2")
library("scales")
labels_euro <- function(x) {
paste0("€", format(x, big.mark = ",", decimal.mark = ".", trim = TRUE,
scientific = FALSE))
}
labels_dollar <- function(x) {
paste0("$", format(x, big.mark = ",", decimal.mark = ".", trim = TRUE,
scientific = FALSE))
}
df <- data.frame(
Year = as.Date(c("2001", "2002", "2003", "2004", "2005", "2006", "2007", "2008", "2009", "2010", "2011", "2012", "2013", "2014", "2015", "2016", "2017", "2018"),
"%Y"),
Dollar = c(0, 9000000, 1000000, 8000000, 2000000, 7000000, 3000000, 6000000, 4000000, 5000000, 5000000, 6000000, 4000000, 7000000, 300000, 8000000, 2000000, 9000000))
df <- cbind(df, Euro = 0.8 * df$Dollar)
p1 <- ggplot(data = df, aes(x = Year, y = Dollar)) +
geom_line(linestyle = "blank") +
theme_bw(20) +
scale_x_date(labels = date_format("%Y"), breaks = date_breaks("2 years")) +
scale_y_continuous(labels = labels_dollar,
breaks = seq(from = 0, to = 8000000, by = 2000000))
p2 <- ggplot(data = df, aes(x = Year, y = Euro)) +
geom_line(color = "blue", linestyle = "dotted", size = 1) +
xlab(NULL) +
theme_bw(20) +
scale_x_date(labels = date_format("%Y"), breaks = date_breaks("2 years")) +
scale_y_continuous(labels = labels_euro,
breaks = seq(from = 0, to = 7000000, by = 2000000))
p <- ggplot_dual_axis(lhs = p1, rhs = p2)
p
pdf("ggplot-dual-axis-function-test.pdf",
encoding = "ISOLatin9.enc", width = 12, height = 8)
p
dev.off()
embedFonts(file = "ggplot-dual-axis-function-test.pdf",
outfile = "ggplot-dual-axis-function-test-embedded.pdf")
![输入图像描述](https://istack.dev59.com/ye3nK.webp)
参考文献列表:
- 在ggplot中显示两个平行坐标轴(R)
- 在多面板图中为ggplot2设置双y轴
- 如何在ggplot2的右侧放置一个变换比例尺?
- 使用grid.arrange保留图形比例
- 在ggplot中对齐图形的风险
- https://github.com/kohske/ggplot2