r中具有不同时间分辨率的堆栈图

stack graphs with different temporal resolution in r

我正在尝试使用 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)

设置

为了便于重现,我将使用 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(),因为它缺少我们需要的一些功能 寻求解决方案。)

识别问题

我们可以确定两个需要注意的问题:

  1. 各个地块的 x-axis 限制必须相等。
  2. 绘图区域需要对齐。 (不同的 y-axis 标签长度导致 绘图区域的大小不同。)

解决方案

第一个问题可以通过创建一个坐标来解决object 定义我们想要的 x-axis 限制。有了列表中的情节,这很容易 使用 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 我们可以通过添加一些额外的 space 来排列绘图区域的选项 在需要的轴标题和轴标签之间。

结果

解决了这两个问题,结果如下:

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。