我正在尝试使用ggplot2和网格排列来堆叠三个图形。所有三个图应具有相同的x轴(但不能共享),问题是它们都具有不同的时间分辨率,而且我很难对齐三个不同图的轴。
这就是我所拥有的:
我想要类似的东西:
数据集土壤温度
average
3/1/2018 11:00 9.353692972
3/1/2018 12:00 10.75947564
3/1/2018 13:00 11.56223312
3/1/2018 14:00 11.59511989
3/1/2018 15:00 11.07712308
3/1/2018 16:00 9.762939639
3/1/2018 17:00 7.650089417
3/1/2018 18:00 6.021789611
3/1/2018 19:00 4.844122056
3/1/2018 20:00 3.946675139
3/1/2018 21:00 3.265207733
3/1/2018 22:00 2.751823167
3/1/2018 23:00 2.307551222
3/2/2018 0:00 1.977323322
3/2/2018 1:00 1.714310775
3/2/2018 2:00 1.505199708
3/2/2018 3:00 1.402693267
3/2/2018 4:00 1.384921586
3/2/2018 5:00 1.350009046
....
数据集ppt
3/1/2018 0
3/2/2018 0
3/3/2018 0
3/4/2018 0
3/5/2018 0
3/6/2018 0
3/7/2018 0
3/8/2018 0
3/9/2018 0
3/10/2018 0
3/11/2018 0
3/12/2018 0
3/13/2018 0
3/14/2018 0
数据集通量
DPF U N
7.08 0.00 0.00
14 0.01 0.02
22 0.16 0.25
29.21 0.00 0.00
33.88 0.05 0.00
42.08 0.00 0.00
代码
# define sheets
hourly <- read_excel("ashland2_graphs.xlsx", sheet = 'Hourly')
daily <- read_excel("ashland2_graphs.xlsx", sheet = 'Climate')
nh3flux <-read_excel('ashland2_graphs.xlsx', sheet = 'flux')
# define soil temp
soiltemp <- as.numeric(as.character(hourly$average))
# soil temperature graph
# define x axis
x = c(1:length(soiltemp))
fig1 <- ggplot()+
geom_line(aes(x=x,y = soiltemp), stat = 'identity') +
scale_x_continuous(breaks = seq(1, length(soiltemp), by = 240),
label = c('0', '10', '20', '30', '40'))
# precipitation graph
ppt <- as.numeric(as.character(daily$ppt))
# precip x axis
x2 = c(1:length(ppt))
fig2 <- ggplot(climate) +
geom_bar(aes(x = x2, y = ppt), stat = 'identity', color = "grey") +
scale_y_continuous(expand = c(0, 0))
print(fig2)
# Losses
urea <- as.numeric(as.character(nh3flux$`NH3 Flux g/m2 day-1 - urea`))
nbpt <- as.numeric(as.character(nh3flux$`NH3 Flux g/m2 day-1 - nbpt`))
x3 <- nh3flux$`Days post fertilization`
fig3 <- ggplot(nh3flux) +
geom_point(mapping = aes(x = x3, y = urea)) +
geom_line(mapping = aes(x = x3, y = urea)) +
geom_point(mapping = aes(x = x3, y = nbpt)) +
geom_line(mapping = aes(x = x3, y = nbpt), linetype = 'dashed') +
scale_x_continuous(breaks=seq(0, 45, 10), limits = c(0, 45))
print(fig3)
# stack graphs
grid.arrange(fig3, fig2, fig1, ncol = 1)
答案 0 :(得分:1)
为了易于重现,我将使用mtcars
数据集
演示如何解决这个问题。首先,让我们创建三个图:
library(ggplot2)
set.seed(123)
dfs <- split(mtcars, sample(3, nrow(mtcars), replace = TRUE))
# Three plots, with the same x variable but different y and geoms
p1 <- ggplot(dfs[[1]], aes(wt, mpg)) + geom_point()
p2 <- ggplot(dfs[[2]], aes(wt)) + geom_histogram()
p3 <- ggplot(dfs[[3]], aes(wt, cyl)) + geom_smooth()
plots <- list(p1, p2, p3) # easier to work with them all in a list
这是堆积的图,显示出与您同样的问题:
cowplot::plot_grid(plotlist = plots, ncol = 1)
#> `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
#> `geom_smooth()` using method = 'loess' and formula 'y ~ x'
(我不使用grid.arrange()
,因为它缺少我们需要的某些功能
寻找解决方案。)
我们可以确定两个需要注意的问题:
第一个问题可以通过创建单个坐标对象来解决
定义我们想要的x轴限制。通过列表中的图,很容易
使用lapply()
将此坐标系应用于每个坐标系:
common_coord <- coord_cartesian(xlim = c(1.5, 5.5))
common_x_plots <- lapply(plots, `+`, common_coord)
对于您的数据,将限制设置为c(0, 45)
可以很好地解决问题。
第二个问题比较棘手,我不认为gridExtra::grid.arrange()
不需要很多额外的工作就可以解决它。这就是为什么我会建议
使用 cowplot 包中的plot_grid()
:它有一个align
我们可以通过添加一些额外的空间来排列绘图区域的选项
轴标题和轴标签之间的位置。
解决了两个问题后,结果如下:
cowplot::plot_grid(plotlist = common_x_plots, ncol = 1, align = "v")
#> `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
#> `geom_smooth()` using method = 'loess' and formula 'y ~ x'
采用这种方法,您也应该可以使用真实数据来实现所需的功能。
由reprex package(v0.2.0.9000)于2018-08-24创建。