我怎么能把一个转换的规模在ggplot2的右侧?
我正在创build一个图表,显示随着时间的推移湖面水平的变化。 我附上了一个简单的例子。 我想添加一个比例尺(刻度线和注释)在图表的右侧,显示以英尺为单位的高程。 我知道ggplot2不会允许两个不同的尺度(见2 y轴,一个y轴在左边,另一个y轴在右边 ),但是因为这是一个相同比例的变换,有没有办法做这个? 我宁愿继续使用ggplot2,而不必恢复到plot()函数。
library(ggplot2) LakeLevels<-data.frame(Day=c(1:365),Elevation=sin(seq(0,2*pi,2*pi/364))*10+100) p <- ggplot(data=LakeLevels) + geom_line(aes(x=Day,y=Elevation)) + scale_y_continuous(name="Elevation (m)",limits=c(75,125)) p
你应该看看这个链接http://rpubs.com/kohske/dual_axis_in_ggplot2 。
我已经调整了你的例子中提供的代码。 这个修复看起来很“黑客”,但它让你成为那里的一部分。 剩下的唯一部分就是搞清楚如何将文本添加到图的右侧。
library(ggplot2) library(gtable) library(grid) LakeLevels<-data.frame(Day=c(1:365),Elevation=sin(seq(0,2*pi,2*pi/364))*10+100) p1 <- ggplot(data=LakeLevels) + geom_line(aes(x=Day,y=Elevation)) + scale_y_continuous(name="Elevation (m)",limits=c(75,125)) p2<-ggplot(data=LakeLevels)+geom_line(aes(x=Day, y=Elevation))+ scale_y_continuous(name="Elevation (ft)", limits=c(75,125), breaks=c(80,90,100,110,120), labels=c("262", "295", "328", "361", "394")) #extract gtable g1<-ggplot_gtable(ggplot_build(p1)) g2<-ggplot_gtable(ggplot_build(p2)) #overlap the panel of the 2nd plot on that of the 1st plot 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[[2]] 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) # draw it grid.draw(g)
我可能已经find了一个解决scheme来放置轴标题,从内特教皇的答案,可以在这里find一些想法:
ggplot2:在绘图顶部添加二次转换的x轴
有关在gtable中访问grobs的讨论: https ://groups.google.com/forum/m/#!topic/ggplot2-dev/AVHHcYqc5uU
最后,我刚刚添加了该行
g <- gtable_add_grob(g, g2$grob[[7]], pp$t, length(g$widths), pp$b)
之前调用grid.draw(g)
,这似乎是伎俩。
据我所知,它采用Y轴标题g2$grob[[7]]
,并将其放在最右侧。 这可能不是美人儿的解决scheme,但它为我工作。
最后一件事。 这将是很好的find一种方法来旋转轴标题。
问候,
蒂姆
这个问题已经得到了解答,但是在ggplot对象的右边添加第二轴和第二个缩放的一般问题是始终出现的问题。 我想在这个问题的基础上,根据在这个线程以及其他几个线程(见下面的参考文献的部分列表)中的各种答案给出的几个元素,我自己调整的问题。
我需要大量生产双Y轴图,所以我build立了一个函数ggplot_dual_axis()
。 以下是潜在的兴趣特征:
-
代码显示y轴和y轴的网格线 (这是我的主要贡献,尽pipe它是微不足道的)
-
代码打印一个欧元符号,并将其embedded到pdf (我看到的东西: 在ggplot2中绘制欧元符号€? )
-
代码试图避免打印某些元素两次(“尝试”暗示我怀疑它完全成功)
未解答的问题:
-
有没有一种方法来修改
ggplot_dual_axis()
函数来删除geom_line()
或geom_point()
或者如果这样的geom元素不存在,不会抛出错误。 在伪代码的东西,if has(geom_line) ...
-
我怎么能通过关键字而不是索引来调用
g2$grobs[[7]]
? 这就是它返回的内容:text[axis.title.y.text.232]
我对这个问题的兴趣来源于我尝试使用类似的技巧来获取网格线的失败尝试。 我认为网格线隐藏在g2$grobs[[4]]
某处,但我不确定如何访问它们。
编辑 。 问题我能够回答自己:我怎样才能增加右边的“欧元”标签的情节边界? 答案:例如, theme(plot.margin = unit(c(1,3,0.5,0.8), "lines"))
就可以做到这一点。
请指出任何明显的问题或build议改进。
现在的代码:希望对某人有用。 正如我所说,我不要求独创性,这是别人已经显示的东西的组合。
##' function named ggplot_dual_axis() ##' Takes 2 ggplot plots and makes a dual y-axis plot ##' function takes 2 compulsory arguments and 1 optional argument ##' arg lhs is the ggplot whose y-axis is to be displayed on the left ##' arg rhs is the ggplot whose y-axis is to be displayed on the right ##' arg 'axis.title.y.rhs' takes value "rotate" to rotate right y-axis label ##' The function does as little as possible, namely: ##' # display the lhs plot without minor grid lines and with a ##' transparent background to allow grid lines to show ##' # display the rhs plot without minor grid lines and with a ##' secondary y axis, a rotated axis label, without minor grid lines ##' # justify the y-axis label by setting 'hjust = 0' in 'axis.text.y' ##' # rotate the right plot 'axis.title.y' by 270 degrees, for symmetry ##' # rotation can be turned off with 'axis.title.y.rhs' option ##' ggplot_dual_axis <- function(lhs, rhs, axis.title.y.rhs = "rotate") { # 1. Fix the right y-axis label justification rhs <- rhs + theme(axis.text.y = element_text(hjust = 0)) # 2. Rotate the right y-axis label by 270 degrees by default if (missing(axis.title.y.rhs) | axis.title.y.rhs %in% c("rotate", "rotated")) { rhs <- rhs + theme(axis.title.y = element_text(angle = 270)) } # 3a. Use only major grid lines for the left axis lhs <- lhs + theme(panel.grid.minor = element_blank()) # 3b. Use only major grid lines for the right axis # force transparency of the backgrounds to allow grid lines to show rhs <- rhs + theme(panel.grid.minor = element_blank(), panel.background = element_rect(fill = "transparent", colour = NA), plot.background = element_rect(fill = "transparent", colour = NA)) # Process gtable objects # 4. Extract gtable library("gtable") # loads the grid package g1 <- ggplot_gtable(ggplot_build(lhs)) g2 <- ggplot_gtable(ggplot_build(rhs)) # 5. Overlap the panel of the rhs plot on that of the lhs plot 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) # Tweak axis position and labels ia <- which(g2$layout$name == "axis-l") ga <- g2$grobs[[ia]] ax <- ga$children[["axis"]] # ga$children[[2]] 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) # Display plot with arrangeGrob wrapper arrangeGrob(g) library("gridExtra") grid.newpage() return(arrangeGrob(g)) }
还有一些假的数据和两个计划是以美元和欧元为单位的。 如果有一个软件包可以让你创build一个graphics,并绕过它,调用一个双y坐标图,就像ggplot_dual_axis_er(ggplot_object, currency = c("dollar", "euro"))
,它会自动为您获取汇率! 🙂
# Set directory: if(.Platform$OS.type == "windows"){ setwd("c:/R/plots") } else { setwd("~/R/plots") } # Load libraries library("ggplot2") library("scales") # Create euro currency symbol in plot labels, simple version # avoids loading multiple libraries # avoids problems with rounding of small numbers, eg .0001 labels_euro <- function(x) {# no rounding paste0("€", format(x, big.mark = ",", decimal.mark = ".", trim = TRUE, scientific = FALSE)) } labels_dollar <- function(x) {# no rounding: overwrites dollar() of library scales paste0("$", format(x, big.mark = ",", decimal.mark = ".", trim = TRUE, scientific = FALSE)) } # Create data 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)) # set Euro/Dollar exchange rate at 0.8 euros = 1 dollar df <- cbind(df, Euro = 0.8 * df$Dollar) # Left y-axis p1 <- ggplot(data = df, aes(x = Year, y = Dollar)) + geom_line(linestyle = "blank") + # manually remove the line theme_bw(20) + # make sure font sizes match in both plots 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)) # Right y-axis p2 <- ggplot(data = df, aes(x = Year, y = Euro)) + geom_line(color = "blue", linestyle = "dotted", size = 1) + xlab(NULL) + # manually remove the label theme_bw(20) + # make sure font sizes match in both plots 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)) # Combine left y-axis with right y-axis p <- ggplot_dual_axis(lhs = p1, rhs = p2) p # Save to PDF 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")
部分参考清单:
- 在ggplot(R)上显示两个平行轴
- ggplot2中的双y轴用于多个面板graphics
- 我怎么能把一个转换的规模在ggplot2的右侧?
- 使用grid.arrange保留图的比例
- 在ggplot中alignment图的危险
- https://github.com/kohske/ggplot2
为了旋转轴标题,将以下内容添加到p2图中:
p2 <- p2 + theme(axis.title.y=element_text(angle=270))