[英]ggplot2: Adding secondary transformed x-axis on top of plot
[ Edit April 2016: the solution in this thread no longer displays the added axis correctly - a new thread on this issue has been opened at ggplot2 2.1.0 broke my code? [ 编辑2016年4月:此线程中的解决方案不再正确显示添加的轴 - 此问题的新线程已在ggplot2打开2.1.0打破了我的代码? Secondary transformed axis now appears incorrectly ]
二次变换轴现在显示不正确 ]
I am working with scaled x data, and need to add an unscaled x axis to the top of the plot for easier interpretation. 我正在使用缩放的x数据,并且需要在绘图顶部添加一个未缩放的x轴以便于解释。 I've come across an approach for adding a secondary a y-axis at How can I put a transformed scale on the right side of a ggplot2?
我遇到了一个添加辅助y轴的方法我如何在ggplot2的右侧放置一个转换后的比例? .
。 However, I can't get it to work properly for the x-axis.
但是,我无法让它在x轴上正常工作。 I'm sure i'm not understanding some part of the code, but I can't seem to figure out what it is.
我确定我不理解代码的某些部分,但我似乎无法弄清楚它是什么。 I've tried looking in the ggplot2 help files, and also the Wickham book ggplot2: Elegant Graphics For Data Analysis, but if anyone can point me towards some relevant documentation I would really appreciate it!
我已经尝试过查看ggplot2帮助文件,以及Wickham书籍ggplot2:数据分析的优雅图形,但如果有人能指出我的一些相关文档,我会非常感激!
I am working with temperature data, but I will use the lake data from the link above as the code was written for that. 我正在使用温度数据,但是我将使用上面链接中的湖泊数据作为代码。 Here is the orignal code from that link:
以下是该链接的原始代码:
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)
To test a method for adding an x-axis instead of y-axis, I switched the x and y axes and changed axis-l
to axis-b
to give: 为了测试添加x轴而不是y轴的方法,我切换了x和y轴,并将
axis-l
更改为axis-b
以给出:
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=Elevation,y=Day)) +
scale_x_continuous(name="Elevation (m)",limits=c(75,125))
p2<-ggplot(data=LakeLevels)+geom_line(aes(x=Elevation, y=Day))+
scale_x_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-b")
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)
This produces a new x-axis, but there are a couple of problems: 1) it is in the middle of the plot 2) it does not produce a new x-label for "Elevation (ft)" 这会产生一个新的x轴,但是存在一些问题:1)它位于图2的中间2)它不会为“Elevation(ft)”生成新的x标签
I need the axis to appear at the top of the plot, and I need an associated axis label. 我需要轴出现在图的顶部,我需要一个关联的轴标签。 Can anyone tell me what I am doing wrong?
谁能告诉我我做错了什么?
Also, as mentioned above, I am working with scaled temperature data, so ideally the ticks would not align on the top and bottom axes as they do in this example. 另外,如上所述,我正在使用缩放的温度数据,因此理想情况下,刻度线不会像在此示例中那样在顶轴和底轴上对齐。 Is there any way to do this in ggplot2?
有没有办法在ggplot2中这样做? An arbitrary example from the web is this:
来自网络的任意例子是这样的:
The root of your problem is that you are modifying columns and not rows. 您的问题的根源是您正在修改列而不是行。
The setup, with scaled labels on the X-axis of the second plot: 设置,第二个图的X轴上带有缩放标签:
## 'base' plot
p1 <- ggplot(data=LakeLevels) + geom_line(aes(x=Elevation,y=Day)) +
scale_x_continuous(name="Elevation (m)",limits=c(75,125))
## plot with "transformed" axis
p2<-ggplot(data=LakeLevels)+geom_line(aes(x=Elevation, y=Day))+
scale_x_continuous(name="Elevation (ft)", limits=c(75,125),
breaks=c(90,101,120),
labels=round(c(90,101,120)*3.24084) ## labels convert to feet
)
## 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)
EDIT to have the grid lines align with the lower axis ticks, replace the above line with: g <- gtable_add_grob(g1, g1$grobs[[which(g1$layout$name=="panel")]], pp$t, pp$l, pp$b, pp$l)
编辑以使网格线与下轴刻度对齐,将上面的行替换为:
g <- gtable_add_grob(g1, g1$grobs[[which(g1$layout$name=="panel")]], pp$t, pp$l, pp$b, pp$l)
## steal axis from second plot and modify
ia <- which(g2$layout$name == "axis-b")
ga <- g2$grobs[[ia]]
ax <- ga$children[[2]]
Now, you need to make sure you are modifying the correct dimension. 现在,您需要确保修改正确的尺寸。 Because the new axis is horizontal (a row and not a column),
whatever_grob$heights
is the vector to modify to change the amount of vertical space in a given row. 因为新轴是水平的(行而不是列),
whatever_grob$heights
是要修改的向量,以更改给定行中的垂直空间量。 If you want to add new space, make sure to add a row and not a column (ie. use gtable_add_rows()
). 如果要添加新空间,请确保添加行而不是列(即使用
gtable_add_rows()
)。
If you are modifying grobs themselves (in this case we are changing the vertical justification of the ticks), be sure to modify the y
(vertical position) rather than x
(horizontal position). 如果你自己修改凹凸(在这种情况下我们正在改变刻度的垂直对齐),一定要修改
y
(垂直位置)而不是x
(水平位置)。
## switch position of ticks and labels
ax$heights <- rev(ax$heights)
ax$grobs <- rev(ax$grobs)
ax$grobs[[2]]$y <- ax$grobs[[2]]$y - unit(1, "npc") + unit(0.15, "cm")
## modify existing row to be tall enough for axis
g$heights[[2]] <- g$heights[g2$layout[ia,]$t]
## add new axis
g <- gtable_add_grob(g, ax, 2, 4, 2, 4)
## add new row for upper axis label
g <- gtable_add_rows(g, g2$heights[1], 1)
g <- gtable_add_grob(g, g2$grob[[6]], 2, 4, 2, 4)
# draw it
grid.draw(g)
I'll note in passing that gtable_show_layout()
is a very, very handy function for figuring out what is going on. 我会顺便注意到
gtable_show_layout()
是一个非常非常方便的函数,用于确定发生了什么。
You can use sec_axis
or dup_axis
. 您可以使用
sec_axis
或dup_axis
。
library(ggplot2)
ggplot(mtcars, aes(x=disp, y=mpg, color=as.factor(cyl))) +
geom_point() +
labs(x="displacement (cubic inches)", col="# of cylinders") +
scale_x_continuous(sec.axis=sec_axis(trans=~ . * 0.0163871, name="displacement (L)"))
ggplot2
version 3.1.1 ggplot2
版本3.1.1
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.