[英]R, ggplot - Graphs sharing the same y-axis but with different x-axis scales
我有一些数据集/变量,我想绘制它们,但我想以紧凑的方式进行。 为此,我希望它们共享相同的 y 轴但不同的 x 轴,并且由于分布不同,我希望 x 轴之一对数缩放,另一个线性缩放。
假设我有一个长尾变量(我希望在绘制时对 x 轴进行对数缩放):
library(PtProcess)
library(ggplot2)
set.seed(1)
lambda <- 1.5
a <- 1
pareto <- rpareto(1000,lambda=lambda,a=a)
x_pareto <- seq(from=min(pareto),to=max(pareto),length=1000)
y_pareto <- 1-ppareto(x_pareto,lambda,a)
df1 <- data.frame(x=x_pareto,cdf=y_pareto)
ggplot(df1,aes(x=x,y=cdf)) + geom_line() + scale_x_log10()
和一个正常的变量:
set.seed(1)
mean <- 3
norm <- rnorm(1000,mean=mean)
x_norm <- seq(from=min(norm),to=max(norm),length=1000)
y_norm <- pnorm(x_norm,mean=mean)
df2 <- data.frame(x=x_norm,cdf=y_norm)
ggplot(df2,aes(x=x,y=cdf)) + geom_line()
我想使用相同的 y 轴并排绘制它们。
我可以用看起来很棒的面来做到这一点,但我不知道如何使每个 x 轴具有不同的比例( scale_x_log10()
使它们都对数缩放):
df1 <- cbind(df1,"pareto")
colnames(df1)[3] <- 'var'
df2 <- cbind(df2,"norm")
colnames(df2)[3] <- 'var'
df <- rbind(df1,df2)
ggplot(df,aes(x=x,y=cdf)) + geom_line() +
facet_wrap(~var,scales="free_x") + scale_x_log10()
使用grid.arrange
,但我不知道如何保持两个绘图区域具有相同的纵横比:
library(gridExtra)
p1 <- ggplot(df1,aes(x=x,y=cdf)) + geom_line() + scale_x_log10() +
theme(plot.margin = unit(c(0,0,0,0), "lines"),
plot.background = element_blank()) +
ggtitle("pareto")
p2 <- ggplot(df2,aes(x=x,y=cdf)) + geom_line() +
theme(axis.text.y = element_blank(),
axis.ticks.y = element_blank(),
axis.title.y = element_blank(),
plot.margin = unit(c(0,0,0,0), "lines"),
plot.background = element_blank()) +
ggtitle("norm")
grid.arrange(p1,p2,ncol=2)
PS:地块的数量可能会有所不同,所以我不是在寻找专门针对 2 个地块的答案
扩展您的尝试 #2, gtable
可能会帮助您。 如果两个图表中的边距相同,那么两个图中唯一变化的宽度(我认为)是 y 轴刻度标记标签和轴文本占用的空间,这反过来又会改变面板的宽度. 使用这里的代码,轴文本占用的空间应该相同,因此两个面板区域的宽度应该相同,因此纵横比应该相同。 然而,结果(没有右边距)看起来并不漂亮。 所以我在 p2 的右边加了一点边距,然后在 p2 的左边去掉了相同的量。 同样对于 p1:我在左边添加了一点,但在右边去掉了相同的数量。
library(PtProcess)
library(ggplot2)
library(gtable)
library(grid)
library(gridExtra)
set.seed(1)
lambda <- 1.5
a <- 1
pareto <- rpareto(1000,lambda=lambda,a=a)
x_pareto <- seq(from=min(pareto),to=max(pareto),length=1000)
y_pareto <- 1-ppareto(x_pareto,lambda,a)
df1 <- data.frame(x=x_pareto,cdf=y_pareto)
set.seed(1)
mean <- 3
norm <- rnorm(1000,mean=mean)
x_norm <- seq(from=min(norm),to=max(norm),length=1000)
y_norm <- pnorm(x_norm,mean=mean)
df2 <- data.frame(x=x_norm,cdf=y_norm)
p1 <- ggplot(df1,aes(x=x,y=cdf)) + geom_line() + scale_x_log10() +
theme(plot.margin = unit(c(0,-.5,0,.5), "lines"),
plot.background = element_blank()) +
ggtitle("pareto")
p2 <- ggplot(df2,aes(x=x,y=cdf)) + geom_line() +
theme(axis.text.y = element_blank(),
axis.ticks.y = element_blank(),
axis.title.y = element_blank(),
plot.margin = unit(c(0,1,0,-1), "lines"),
plot.background = element_blank()) +
ggtitle("norm")
gt1 <- ggplotGrob(p1)
gt2 <- ggplotGrob(p2)
newWidth = unit.pmax(gt1$widths[2:3], gt2$widths[2:3])
gt1$widths[2:3] = as.list(newWidth)
gt2$widths[2:3] = as.list(newWidth)
grid.arrange(gt1, gt2, ncol=2)
编辑要在右侧添加第三个绘图,我们需要对绘图画布进行更多控制。 一种解决方案是创建一个新的 gtable,其中包含三个绘图的空间和一个用于右边距的额外空间。 在这里,我让图中的边距处理图之间的间距。
p1 <- ggplot(df1,aes(x=x,y=cdf)) + geom_line() + scale_x_log10() +
theme(plot.margin = unit(c(0,-2,0,0), "lines"),
plot.background = element_blank()) +
ggtitle("pareto")
p2 <- ggplot(df2,aes(x=x,y=cdf)) + geom_line() +
theme(axis.text.y = element_blank(),
axis.ticks.y = element_blank(),
axis.title.y = element_blank(),
plot.margin = unit(c(0,-2,0,0), "lines"),
plot.background = element_blank()) +
ggtitle("norm")
gt1 <- ggplotGrob(p1)
gt2 <- ggplotGrob(p2)
newWidth = unit.pmax(gt1$widths[2:3], gt2$widths[2:3])
gt1$widths[2:3] = as.list(newWidth)
gt2$widths[2:3] = as.list(newWidth)
# New gtable with space for the three plots plus a right-hand margin
gt = gtable(widths = unit(c(1, 1, 1, .3), "null"), height = unit(1, "null"))
# Instert gt1, gt2 and gt2 into the new gtable
gt <- gtable_add_grob(gt, gt1, 1, 1)
gt <- gtable_add_grob(gt, gt2, 1, 2)
gt <- gtable_add_grob(gt, gt2, 1, 3)
grid.newpage()
grid.draw(gt)
公认的答案正是让人们在使用 R 绘图时奔跑的原因! 这是我的解决方案:
library('grid')
g1 <- ggplot(...) # however you draw your 1st plot
g2 <- ggplot(...) # however you draw your 2nd plot
grid.newpage()
grid.draw(cbind(ggplotGrob(g1), ggplotGrob(g2), size = "last"))
这会处理 y 轴(次要和主要)指南,以毫不费力地在多个图中对齐。
删除一些轴文本,统一图例,...,是在创建单个绘图时可以处理的其他任务,或者使用grid或gridExtra包提供的其他方法。
接受的答案对我来说有点太令人生畏了。 所以我找到了两种方法来以较少的努力解决它。 两者都基于您的尝试 #2 grid.arrange()
方法。
theme(axis.text.y = element_blank(), axis.ticks.y = element_blank(), axis.title.y = element_blank()
所以所有的情节都是一样的。 您不会遇到不同纵横比的问题。 您需要使用 R 或您喜欢的图像编辑应用程序生成单独的 y 轴。
2.修复和尊重纵横比将aspect.ratio = 1
或您想要的任何比例添加到单个图的theme()
。 然后在你的grid.arrange()
使用respect=TRUE
通过这种方式,您可以将 y 轴保留在 plot1 中,并且仍然保持所有图中的纵横比。 受到这个答案的启发。
希望你觉得这些有用!
我正在尝试为每个变量创建一个图表,然后将这些变量放在一起,具有相同的 y 轴和一个 x 轴标签。
这段代码几乎可以工作,但每个图形的轴仍然重复。
p1 <- ggplot().....
p2 <- ggplot().....
grid.newpage()
grid.draw(cbind(ggplotGrob(p1), ggplotGrob(p2), size = "last"))
@Azim 建议的代码行
我不太确定是否有比在 p1 <- ggplot() 级别删除它们更简单的方法来消除 y 轴。 我也不知道如何将 x 轴移动到中间...
一些视觉帮助:
感谢您的任何建议!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.