R - RStudio 中每页多图
R - Multiple plots per page in RStudio
我有三个降水数据集:一个观测值和两组模型:原始模型和偏差校正模型。每组包含五个模型:CanESM2, GFDL.ESM2M, MRI.CGCM3, NorESM1.M, inmcm4
.
以下代码重现了我的数据:
obs <- c(8.12903225806452, 4.65483870967742, 4.00967741935484, 2.82903225806452,
1.02258064516129, 4.94838709677419, 2.03548387096774, 4.56129032258065,
6.66451612903226, 10.4129032258065, 3.7741935483871, 9.93870967741936)
uncorrected <- structure(list(CanESM2 = c(3.71099209785461, 6.68828105926514,
4.2675461769104, 4.29092979431152, 6.47999143600464, 6.30958032608032,
3.28256869316101, 1.06898427009583, 4.01592206954956, 7.88787031173706,
10.8663206100464, 9.14756298065186), GFDL.ESM2M = c(4.56643295288086,
8.36136913299561, 4.6934700012207, 4.62750291824341, 6.34791326522827,
0.916408598423004, 0.111764870584011, 0.570569038391113, 3.05491662025452,
3.29908037185669, 5.98263263702393, 7.52161026000977), MRI.CGCM3 = c(3.94400858879089,
2.48861312866211, 0.663281202316284, 0.422377318143845, 1.49548053741455,
1.8869035243988, 5.35201597213745, 3.94722390174866, 5.0041446685791,
6.11909627914429, 6.37435054779053, 5.9401068687439), NorESM1.M = c(8.83542060852051,
8.36209106445312, 3.22844076156616, 2.86131143569946, 2.05858564376831,
2.39689040184021, 1.06175291538239, 1.03921580314636, 2.49208211898804,
6.83605766296387, 7.95251750946045, 4.8852391242981), inmcm4 = c(5.88600730895996,
8.03514385223389, 3.86212635040283, 1.51728367805481, 3.46821308135986,
1.30993270874023, 0.497318655252457, 0.589299857616425, 1.63358855247498,
3.61927103996277, 4.99840354919434, 10.5596942901611)), .Names = c("CanESM2",
"GFDL.ESM2M", "MRI.CGCM3", "NorESM1.M", "inmcm4"), class = "data.frame", row.names = c(NA,
-12L))
corrected <- structure(list(CanESM2 = c(4.69295692443848, 6.2362003326416,
4.48602199554443, 4.21368360519409, 6.02497625350952, 5.94498348236084,
3.92529225349426, 1.07059073448181, 3.92306709289551, 8.00215721130371,
10.9688482284546, 9.95723056793213), GFDL.ESM2M = c(6.74847173690796,
10.7781000137329, 6.89084196090698, 7.5780816078186, 8.96726703643799,
3.57111501693726, 1.20403492450714, 2.76221370697021, 4.98387718200684,
5.27927255630493, 8.87845706939697, 9.95864582061768), MRI.CGCM3 = c(5.45173072814941,
3.37272930145264, 2.20000958442688, 1.12101686000824, 2.67246603965759,
3.10278224945068, 6.02392053604126, 4.70185708999634, 5.86025190353394,
6.41299057006836, 7.1956262588501, 7.59840393066406), NorESM1.M = c(9.49540519714355,
9.88559532165527, 4.86537599563599, 4.56189870834351, 3.85974431037903,
4.07706260681152, 2.55634951591492, 2.63215637207031, 4.21092081069946,
7.66422271728516, 8.75070095062256, 5.95497798919678), inmcm4 = c(8.21576976776123,
11.1972188949585, 6.08181619644165, 3.58428621292114, 5.543297290802,
3.46666693687439, 1.88991332054138, 1.94812619686127, 3.71879911422729,
5.70409107208252, 6.85269260406494, 11.8774194717407)), .Names = c("CanESM2",
"GFDL.ESM2M", "MRI.CGCM3", "NorESM1.M", "inmcm4"), class = "data.frame", row.names = c(NA,
-12L))
我需要做的是根据观察结果在模型之间创建 qq 图。因此,我将有 10 个地块(5 个模型 x 2 组模型)。
然后,我需要将所有绘图合并到一页中,在一个 5x2 矩阵中,其中行代表每个模型(CanESM2、GFDL.ESM2M 等),列代表每组模型:原始模型和偏置模型-更正。
我快到了。这是我到目前为止所做的:
par(mfrow=c(5,2))
for (i in 1:length(names(uncorrected))) {
# Plot uncorrected vs obs
qqplot(as.vector(obs), uncorrected[,i], xlim=c(0,14), ylim=c(0,14),
xlab=expression("Obs. precip." ~ (mm ~ day^{-1})),
ylab=expression("Mod. precip." ~ (mm ~ day^{-1})))
abline(0, 1)
# Then plot corrected vs obs
qqplot(as.vector(obs), corrected[,i], xlim=c(0,14), ylim=c(0,14),
xlab=expression("Obs. precip." ~ (mm ~ day^{-1})),
ylab=expression("Mod. precip." ~ (mm ~ day^{-1})))
abline(0, 1)
}
但我在 RStudio 上遇到错误:Error in plot.new() : figure margins too large
我可以在独立的 R 上得到它,但最终的图形看起来真的很糟糕,每个图看起来 "stretched"。
如何将所有这些图形与 RStudio 中可接受的外观结合起来?
你的问题的原因是 mar
参数相对于情节 window 大小来说很大,正如@shayaa 和@Vandenman 所说。这是我用于多图的一组 par()
个参数。 ylab cut的问题通过改变Rstudio的绘图高度window或输出选项来解决。
par.old <- par(no.readonly=T) # save old par
par( mfrow = c(5, 2), mar = c(3, 3, 0.5, 0.5), tcl = -0.3, mgp = c(1.7, 0.4, 0) )
for (i in 1:length(names(uncorrected))) {
# Plot uncorrected vs obs
qqplot(as.vector(obs), uncorrected[,i], xlim=c(0,14), ylim=c(0,14),
xlab=expression("Obs. precip." ~ (mm ~ day^{-1})),
ylab=expression("Mod. precip." ~ (mm ~ day^{-1})))
abline(0, 1)
# Then plot corrected vs obs
qqplot(as.vector(obs), corrected[,i], xlim=c(0,14), ylim=c(0,14),
xlab=expression("Obs. precip." ~ (mm ~ day^{-1})),
ylab=expression("Mod. precip." ~ (mm ~ day^{-1})))
abline(0, 1)
}
par(par.old) # read old par (not necessary)
如果 xlab 和 ylab 对绘图是通用的,您可以通过在外边距处只写一次 xlab 和 ylab 来节省 space。
par( mfrow = c(5, 2), mar = c(1.2, 1.2, 0.5, 0.5), tcl = -0.3, mgp = c(1.7, 0.4, 0),
oma = c(2.5, 2.5, 0, 0) )
for (i in 1:length(names(uncorrected))) {
# Plot uncorrected vs obs
qqplot(as.vector(obs), uncorrected[,i], xlim=c(0,14), ylim=c(0,14), ann=F)
abline(0, 1)
# Then plot corrected vs obs
qqplot(as.vector(obs), corrected[,i], xlim=c(0,14), ylim=c(0,14), ann=F)
abline(0, 1)
}
mtext(side=1, expression("Obs. precip." ~ (mm ~ day^{-1})), outer=T, line=1.1)
mtext(side=2, expression("Mod. precip." ~ (mm ~ day^{-1})), outer=T, line=0.6)
[编辑]
我不认为你需要使用 layout() 除非你想要一个复杂的拆分。
par(mfrow = c(3, 4), mar = c(1.2, 1.2, 0.5, 0.5), tcl = -0.3, mgp = c(1.7, 0.4, 0),
oma = c(2.5, 2.5, 0, 0) )
for (i in 1:length(names(uncorrected))) {
qqplot(as.vector(obs), uncorrected[,i], xlim=c(0,14), ylim=c(0,14), ann=F)
abline(0, 1)
legend("topleft", paste0("uncorrected",i), bty="n") # example
qqplot(as.vector(obs), corrected[,i], xlim=c(0,14), ylim=c(0,14), ann=F)
abline(0, 1)
legend("topleft", paste0("corrected", i), bty="n") # example
}
for(i in 1:2) plot(0, type="n", ann=F, axes=F) # make two blank graphs
mtext(side=1, expression("Obs. precip." ~ (mm ~ day^{-1})), outer=T, line=1.1)
mtext(side=2, expression("Mod. precip." ~ (mm ~ day^{-1})), outer=T, line=0.6)
如果要使用 layout(),最好使用相同的 par()
参数而不使用 mfrow()
。 (下面的代码等同于上面的代码)
m <- matrix(c(1:10, 0, 0), byrow=T, ncol=4)
layout(m)
par( mar = c(1.2, 1.2, 0.5, 0.5), tcl = -0.3, mgp = c(1.7, 0.4, 0),
oma = c(2.5, 2.5, 0, 0) )
for (i in 1:length(names(uncorrected))) {
qqplot(as.vector(obs), uncorrected[,i], xlim=c(0,14), ylim=c(0,14), ann=F)
abline(0, 1)
legend("topleft", paste0("uncorrected",i), bty="n") # example
qqplot(as.vector(obs), corrected[,i], xlim=c(0,14), ylim=c(0,14), ann=F)
abline(0, 1)
legend("topleft", paste0("corrected", i), bty="n") # example
}
mtext(side=1, expression("Obs. precip." ~ (mm ~ day^{-1})), outer=T, line=1.1)
mtext(side=2, expression("Mod. precip." ~ (mm ~ day^{-1})), outer=T, line=0.6)
如果你想重复 NO.9 & 10 图,你应该改变 for()
参数(即 for ( i in c(1:5, 5) )
)(如果使用 layout()
,m <- matrix(c(1:12), byrow=T, ncol=4)
.在layout()
,相同的数字表示对接)
Error in plot.new() : figure margins too large
可能是一个与计算机有关的错误。如果你只是简单地将Rstudio中的plotwindow调整到尽可能大,然后重新运行代码,它还会出现吗?如果是,则可能是 Rstudio 无法在您的机器上显示绘图。您可以通过在绘图之前调用 x11()
来为绘图打开一个新的 window 来解决这个问题(就像 base R 所做的那样),或者您可以使用类似的东西:
pdf('test.pdf')
# make plots
dev.off()
创建包含绘图的 pdf 文档。
我有三个降水数据集:一个观测值和两组模型:原始模型和偏差校正模型。每组包含五个模型:CanESM2, GFDL.ESM2M, MRI.CGCM3, NorESM1.M, inmcm4
.
以下代码重现了我的数据:
obs <- c(8.12903225806452, 4.65483870967742, 4.00967741935484, 2.82903225806452,
1.02258064516129, 4.94838709677419, 2.03548387096774, 4.56129032258065,
6.66451612903226, 10.4129032258065, 3.7741935483871, 9.93870967741936)
uncorrected <- structure(list(CanESM2 = c(3.71099209785461, 6.68828105926514,
4.2675461769104, 4.29092979431152, 6.47999143600464, 6.30958032608032,
3.28256869316101, 1.06898427009583, 4.01592206954956, 7.88787031173706,
10.8663206100464, 9.14756298065186), GFDL.ESM2M = c(4.56643295288086,
8.36136913299561, 4.6934700012207, 4.62750291824341, 6.34791326522827,
0.916408598423004, 0.111764870584011, 0.570569038391113, 3.05491662025452,
3.29908037185669, 5.98263263702393, 7.52161026000977), MRI.CGCM3 = c(3.94400858879089,
2.48861312866211, 0.663281202316284, 0.422377318143845, 1.49548053741455,
1.8869035243988, 5.35201597213745, 3.94722390174866, 5.0041446685791,
6.11909627914429, 6.37435054779053, 5.9401068687439), NorESM1.M = c(8.83542060852051,
8.36209106445312, 3.22844076156616, 2.86131143569946, 2.05858564376831,
2.39689040184021, 1.06175291538239, 1.03921580314636, 2.49208211898804,
6.83605766296387, 7.95251750946045, 4.8852391242981), inmcm4 = c(5.88600730895996,
8.03514385223389, 3.86212635040283, 1.51728367805481, 3.46821308135986,
1.30993270874023, 0.497318655252457, 0.589299857616425, 1.63358855247498,
3.61927103996277, 4.99840354919434, 10.5596942901611)), .Names = c("CanESM2",
"GFDL.ESM2M", "MRI.CGCM3", "NorESM1.M", "inmcm4"), class = "data.frame", row.names = c(NA,
-12L))
corrected <- structure(list(CanESM2 = c(4.69295692443848, 6.2362003326416,
4.48602199554443, 4.21368360519409, 6.02497625350952, 5.94498348236084,
3.92529225349426, 1.07059073448181, 3.92306709289551, 8.00215721130371,
10.9688482284546, 9.95723056793213), GFDL.ESM2M = c(6.74847173690796,
10.7781000137329, 6.89084196090698, 7.5780816078186, 8.96726703643799,
3.57111501693726, 1.20403492450714, 2.76221370697021, 4.98387718200684,
5.27927255630493, 8.87845706939697, 9.95864582061768), MRI.CGCM3 = c(5.45173072814941,
3.37272930145264, 2.20000958442688, 1.12101686000824, 2.67246603965759,
3.10278224945068, 6.02392053604126, 4.70185708999634, 5.86025190353394,
6.41299057006836, 7.1956262588501, 7.59840393066406), NorESM1.M = c(9.49540519714355,
9.88559532165527, 4.86537599563599, 4.56189870834351, 3.85974431037903,
4.07706260681152, 2.55634951591492, 2.63215637207031, 4.21092081069946,
7.66422271728516, 8.75070095062256, 5.95497798919678), inmcm4 = c(8.21576976776123,
11.1972188949585, 6.08181619644165, 3.58428621292114, 5.543297290802,
3.46666693687439, 1.88991332054138, 1.94812619686127, 3.71879911422729,
5.70409107208252, 6.85269260406494, 11.8774194717407)), .Names = c("CanESM2",
"GFDL.ESM2M", "MRI.CGCM3", "NorESM1.M", "inmcm4"), class = "data.frame", row.names = c(NA,
-12L))
我需要做的是根据观察结果在模型之间创建 qq 图。因此,我将有 10 个地块(5 个模型 x 2 组模型)。
然后,我需要将所有绘图合并到一页中,在一个 5x2 矩阵中,其中行代表每个模型(CanESM2、GFDL.ESM2M 等),列代表每组模型:原始模型和偏置模型-更正。
我快到了。这是我到目前为止所做的:
par(mfrow=c(5,2))
for (i in 1:length(names(uncorrected))) {
# Plot uncorrected vs obs
qqplot(as.vector(obs), uncorrected[,i], xlim=c(0,14), ylim=c(0,14),
xlab=expression("Obs. precip." ~ (mm ~ day^{-1})),
ylab=expression("Mod. precip." ~ (mm ~ day^{-1})))
abline(0, 1)
# Then plot corrected vs obs
qqplot(as.vector(obs), corrected[,i], xlim=c(0,14), ylim=c(0,14),
xlab=expression("Obs. precip." ~ (mm ~ day^{-1})),
ylab=expression("Mod. precip." ~ (mm ~ day^{-1})))
abline(0, 1)
}
但我在 RStudio 上遇到错误:Error in plot.new() : figure margins too large
我可以在独立的 R 上得到它,但最终的图形看起来真的很糟糕,每个图看起来 "stretched"。
如何将所有这些图形与 RStudio 中可接受的外观结合起来?
你的问题的原因是 mar
参数相对于情节 window 大小来说很大,正如@shayaa 和@Vandenman 所说。这是我用于多图的一组 par()
个参数。 ylab cut的问题通过改变Rstudio的绘图高度window或输出选项来解决。
par.old <- par(no.readonly=T) # save old par
par( mfrow = c(5, 2), mar = c(3, 3, 0.5, 0.5), tcl = -0.3, mgp = c(1.7, 0.4, 0) )
for (i in 1:length(names(uncorrected))) {
# Plot uncorrected vs obs
qqplot(as.vector(obs), uncorrected[,i], xlim=c(0,14), ylim=c(0,14),
xlab=expression("Obs. precip." ~ (mm ~ day^{-1})),
ylab=expression("Mod. precip." ~ (mm ~ day^{-1})))
abline(0, 1)
# Then plot corrected vs obs
qqplot(as.vector(obs), corrected[,i], xlim=c(0,14), ylim=c(0,14),
xlab=expression("Obs. precip." ~ (mm ~ day^{-1})),
ylab=expression("Mod. precip." ~ (mm ~ day^{-1})))
abline(0, 1)
}
par(par.old) # read old par (not necessary)
如果 xlab 和 ylab 对绘图是通用的,您可以通过在外边距处只写一次 xlab 和 ylab 来节省 space。
par( mfrow = c(5, 2), mar = c(1.2, 1.2, 0.5, 0.5), tcl = -0.3, mgp = c(1.7, 0.4, 0),
oma = c(2.5, 2.5, 0, 0) )
for (i in 1:length(names(uncorrected))) {
# Plot uncorrected vs obs
qqplot(as.vector(obs), uncorrected[,i], xlim=c(0,14), ylim=c(0,14), ann=F)
abline(0, 1)
# Then plot corrected vs obs
qqplot(as.vector(obs), corrected[,i], xlim=c(0,14), ylim=c(0,14), ann=F)
abline(0, 1)
}
mtext(side=1, expression("Obs. precip." ~ (mm ~ day^{-1})), outer=T, line=1.1)
mtext(side=2, expression("Mod. precip." ~ (mm ~ day^{-1})), outer=T, line=0.6)
[编辑]
我不认为你需要使用 layout() 除非你想要一个复杂的拆分。
par(mfrow = c(3, 4), mar = c(1.2, 1.2, 0.5, 0.5), tcl = -0.3, mgp = c(1.7, 0.4, 0),
oma = c(2.5, 2.5, 0, 0) )
for (i in 1:length(names(uncorrected))) {
qqplot(as.vector(obs), uncorrected[,i], xlim=c(0,14), ylim=c(0,14), ann=F)
abline(0, 1)
legend("topleft", paste0("uncorrected",i), bty="n") # example
qqplot(as.vector(obs), corrected[,i], xlim=c(0,14), ylim=c(0,14), ann=F)
abline(0, 1)
legend("topleft", paste0("corrected", i), bty="n") # example
}
for(i in 1:2) plot(0, type="n", ann=F, axes=F) # make two blank graphs
mtext(side=1, expression("Obs. precip." ~ (mm ~ day^{-1})), outer=T, line=1.1)
mtext(side=2, expression("Mod. precip." ~ (mm ~ day^{-1})), outer=T, line=0.6)
如果要使用 layout(),最好使用相同的 par()
参数而不使用 mfrow()
。 (下面的代码等同于上面的代码)
m <- matrix(c(1:10, 0, 0), byrow=T, ncol=4)
layout(m)
par( mar = c(1.2, 1.2, 0.5, 0.5), tcl = -0.3, mgp = c(1.7, 0.4, 0),
oma = c(2.5, 2.5, 0, 0) )
for (i in 1:length(names(uncorrected))) {
qqplot(as.vector(obs), uncorrected[,i], xlim=c(0,14), ylim=c(0,14), ann=F)
abline(0, 1)
legend("topleft", paste0("uncorrected",i), bty="n") # example
qqplot(as.vector(obs), corrected[,i], xlim=c(0,14), ylim=c(0,14), ann=F)
abline(0, 1)
legend("topleft", paste0("corrected", i), bty="n") # example
}
mtext(side=1, expression("Obs. precip." ~ (mm ~ day^{-1})), outer=T, line=1.1)
mtext(side=2, expression("Mod. precip." ~ (mm ~ day^{-1})), outer=T, line=0.6)
如果你想重复 NO.9 & 10 图,你应该改变 for()
参数(即 for ( i in c(1:5, 5) )
)(如果使用 layout()
,m <- matrix(c(1:12), byrow=T, ncol=4)
.在layout()
,相同的数字表示对接)
Error in plot.new() : figure margins too large
可能是一个与计算机有关的错误。如果你只是简单地将Rstudio中的plotwindow调整到尽可能大,然后重新运行代码,它还会出现吗?如果是,则可能是 Rstudio 无法在您的机器上显示绘图。您可以通过在绘图之前调用 x11()
来为绘图打开一个新的 window 来解决这个问题(就像 base R 所做的那样),或者您可以使用类似的东西:
pdf('test.pdf')
# make plots
dev.off()
创建包含绘图的 pdf 文档。