繁体   English   中英

ggplot2:如何在堆叠图形中扩展 y 轴标签

[英]ggplot2: how to extend y-axis labels across stacked figures

我有一个来自两个位置(即Site 1Site 2 )的一年的每日平均温度观测数据框。 三个温度变量是:

  • Air
  • Water
  • Difference = 空气 - 水

我想生成一个四面板图,其中顶行和底行分别是Site 1Site 2 ,左列显示AirWater ,右列显示Difference 我特别没有使用facet_wrap()facet_grid() ,因为 y 轴是两个不同的变量(即温度和温差),并且图例是自定义的。

我可以创建四面板图,但是我希望每列的 y 轴标题不重复。 有没有办法将每个 y 轴标题扩展到每列的堆叠图上?

这是下面图形代码的输出这是我能做的图

理想的身材看起来更像这样但是,我希望这个数字看起来像这样。

示例数据

library(data.table)
library(dplyr)
library(ggplot2)
library(patchwork)

set.seed(321)

# Create the example air and water temperature time series
df1 <- data.frame(matrix(ncol = 4, nrow = 365*4))
colnames(df1)[1:4] <- c("Location","Variable", "Date", "Temperature")
df1[1:730,1] <- "Site 1"
df1[731:NROW(df1),1] <- "Site 2"
df1[c(1:365,731:1095),2] <- "Air"
df1[c(366:730,1096:NROW(df1)),2] <- "Water"
df1$Date <- rep(seq.Date(as.Date("2021-01-01"),as.Date("2021-12-31"),"1 day"),4)
df1$noise <- rep(runif(365),4)
df1$t <- rep(seq(0,1*pi,,365),4)
for (i in 1:NROW(df1)) {
  df1$Temperature[1:365] <- 20*sin(df1$t)+df1$noise*8
  df1$Temperature[365:730] <- 17*sin(df1$t)+df1$noise*2
  df1$Temperature[731:1095] <- 25*sin(df1$t)+df1$noise*6
  df1$Temperature[1096:NROW(df1)] <- 18*sin(df1$t)+df1$noise*1.5
}

# Take the difference between air and water temperature
df1 <- df1[,1:4]
site1 <- df1[df1$Location == 'Site 1',]
site1 <- site1 %>%
  tidyr::pivot_wider(names_from = Variable, values_from = Temperature) %>%
  mutate(Difference = Air - Water)

site2 <- df1[df1$Location == 'Site 2',]
site2 <- site2 %>%
  tidyr::pivot_wider(names_from = Variable, values_from = Temperature) %>%
  mutate(Difference = Air - Water)

图代码

fig1a <- site1 %>%
  ggplot() +
  geom_line(aes(x = Date, y = Air), color = "red", size = 1) +
  geom_line(aes(x = Date, y = Water), size = 1, alpha = 0.7) +
  scale_x_date(date_breaks = "2 month",
               date_labels = "%b",
               expand = c(0, 0)) +
  labs(x = NULL,
       y = expression(paste("Temperature (  ", degree, "C)"))) +
  annotate("rect", fill = "white", color = "black",
           xmin = as.Date("2021-01-15", "%Y-%m-%d"),
           xmax = as.Date("2021-03-15", "%Y-%m-%d"),
           ymin = 26, ymax = 30) +
  annotate("segment", color = "red", size = 1,
           x = as.Date("2021-01-20", "%Y-%m-%d"),
           xend = as.Date("2021-01-30", "%Y-%m-%d"),
           y = 29, yend = 29) +
  annotate("segment", color = "black", size = 1,
           x = as.Date("2021-01-20", "%Y-%m-%d"),
           xend = as.Date("2021-01-30", "%Y-%m-%d"),
           y = 27, yend = 27) +
  annotate("text", x = as.Date("2021-02-01", "%Y-%m-%d"), y = 29,
           label = 'Air',
           size = 5, fontface = 1, hjust = 0) +
  annotate("text", x = as.Date("2021-02-01", "%Y-%m-%d"), y = 27,
           label = "Water",
           size = 5, fontface = 1, hjust = 0) +
  annotate("text", x = as.Date("2021-11-30", "%Y-%m-%d"), y = 30,
           label = "(a",
           size = 6, fontface = 1, hjust = 0) +
  theme_bw() +
  theme(plot.margin = unit(c(0, 1, 0, 1), "lines"),
        panel.grid = element_blank(),
        text = element_text(size = 16),
        axis.text.x = element_text(size = 14, color = "white"),
        axis.text.y = element_text(size = 14, color = "black"),
        panel.border = element_blank()) +
  guides(fill = guide_legend(nrow = 2)) +
  coord_cartesian(clip = 'off', ylim = c(0, 32)) +
  annotation_custom(grid::rectGrob(gp = grid::gpar(fill = NA)))

fig1b <- site2 %>%
  ggplot() +
  geom_line(aes(x = Date, y = Air), color = "red", size = 1) +
  geom_line(aes(x = Date, y = Water), size = 1, alpha = 0.7) +
  scale_x_date(date_breaks = "2 month",
               date_labels = "%b",
               expand = c(0, 0)) +
  labs(x = NULL,
       y = expression(paste("Temperature (  ", degree, "C)"))) +
  annotate("text", x = as.Date("2021-11-30", "%Y-%m-%d"), y = 30,
           label = "(b",
           size = 6, fontface = 1, hjust = 0) +
  theme_bw() +
  theme(plot.margin = unit(c(0, 1, 2, 0), "lines"),
        panel.grid = element_blank(),
        text = element_text(size = 16),
        axis.text.x = element_text(size = 16, color = "black", angle = 90, vjust = 0.5, hjust = 1),
        axis.text.y = element_text(size = 16, color = "black"),
        panel.border = element_blank()) +
  guides(fill = guide_legend(nrow = 2)) +
  coord_cartesian(clip = 'off', ylim = c(0,32)) +
  annotation_custom(grid::rectGrob(gp = grid::gpar(fill = NA))) +
  annotate(geom = "text", x = as.Date("2021-06-15", "%Y-%m-%d"), y = -7, label = 2021, size = 6)

fig1c <- site1 %>%
  ggplot() +
  geom_line(aes(x = Date, y = Difference), size = 1) +
  scale_x_date(date_breaks = "2 month",
               date_labels = "%b",
               expand = c(0, 0)) +
  labs(x = NULL,
       y = expression(paste(Delta~" Temperature (  ",  degree, "C)"))) +
  annotate("rect", fill = "white", color = "black",
           xmin = as.Date("2021-01-15", "%Y-%m-%d"),
           xmax = as.Date("2021-06-01", "%Y-%m-%d"),
           ymin = 10.25, ymax = 12.5) +
  annotate("text", x = as.Date("2021-01-20", "%Y-%m-%d"), y = 12,
           label = 'Pos. = Air > Water',
           size = 5, fontface = 1, hjust = 0) +
  annotate("text", x = as.Date("2021-01-20", "%Y-%m-%d"), y = 11,
           label = "Neg. = Water > Air",
           size = 5, fontface = 1, hjust = 0) +
  annotate("text", x = as.Date("2021-11-30", "%Y-%m-%d"), y = 12,
           label = "(c",
           size = 6, fontface = 1, hjust = 0) +
  theme_bw() +
  theme(plot.margin = unit(c(0, 1, 0, 0), "lines"),
        panel.grid = element_blank(),
        text = element_text(size = 16),
        axis.text.x = element_text(size = 14, color = "white"),
        axis.text.y = element_text(size = 14, color = "black"),
        panel.border = element_blank()) +
  guides(fill = guide_legend(nrow = 2)) +
  coord_cartesian(clip = 'off', ylim = c(-2, 12)) +
  annotation_custom(grid::rectGrob(gp = grid::gpar(fill = NA)))

fig1d <- site2 %>%
  ggplot() +
  geom_line(aes(x = Date, y = Difference), size = 1) +
  scale_x_date(date_breaks = "2 month",
               date_labels = "%b",
               expand = c(0, 0)) +
  labs(x = NULL,
       y = expression(paste(Delta~" Temperature (  ",  degree, "C)"))) +
  annotate("text", x = as.Date("2021-11-30", "%Y-%m-%d"), y = 12,
           label = "(d",
           size = 6, fontface = 1, hjust = 0) +
  theme_bw() +
  theme(plot.margin = unit(c(1, 1, 2, 0), "lines"),
        panel.grid = element_blank(),
        text = element_text(size = 16),
        axis.text.x = element_text(size = 16, color = "black", angle = 90, vjust = 0.5, hjust = 1),
        axis.text.y = element_text(size = 16, color = "black"),
        panel.border = element_blank()) +
  guides(fill = guide_legend(nrow = 2)) +
  coord_cartesian(clip = 'off', ylim = c(-2,12)) +
  annotation_custom(grid::rectGrob(gp = grid::gpar(fill = NA))) +
  annotate(geom = "text", x = as.Date("2021-06-15", "%Y-%m-%d"), y = -5, label = 2021, size = 6)

# width = 1200 height = 900
fig1a + fig1c + fig1b + fig1d + plot_layout(ncol = 2)

我想出了怎么做,这需要使用facet_grid 我最终需要创建两个面,然后将它们缝合在一起,见下文。

# Take the difference between air and water temperature
df1 <- df1[,1:4]
site1 <- df1[df1$Location == 'Site 1',]
site1 <- site1 %>%
  tidyr::pivot_wider(names_from = Variable, values_from = Temperature) %>%
  mutate(Difference = Air - Water) %>%
  tidyr::pivot_longer(cols = c('Water','Air','Difference'),
                      names_to = 'Variable',
                      values_to = 'Temperature')

site2 <- df1[df1$Location == 'Site 2',]
site2 <- site2 %>%
  tidyr::pivot_wider(names_from = Variable, values_from = Temperature) %>%
  mutate(Difference = Air - Water) %>%
  tidyr::pivot_longer(cols = c('Water','Air','Difference'),
                      names_to = 'Variable',
                      values_to = 'Temperature')

df1 <- rbind(site1,site2)

# This creates the first column of figures
p1 <- df1 %>%
  subset(!df1$Variable == 'Difference',) %>%
  mutate(var_air_water = ## Here is the new variable
           if_else(Variable %in% c("Air", "Water"), 
                   true = "Air & Water", 
                   false = Variable)) %>% 
  ggplot() +
  geom_line(aes(x = Date, y = Temperature, group = Variable, color = Variable)) +
  scale_color_manual(values = c("black", "red")) +
  scale_x_date(date_breaks = "2 month",
               date_labels = "%b",
               expand = c(0, 0)) +
  scale_y_continuous(breaks = seq(0,30,5)) +
  labs(x = NULL,
       y = expression(paste("Temperature ( ", degree, "C)"))) +
  theme_bw() +
  theme(plot.margin = unit(c(0, 1, 2, 0), "lines"),
        panel.grid = element_blank(),
        text = element_text(size = 16),
        axis.text.x = element_text(size = 16, color = "black", angle = 90, vjust = 0.5, hjust = 1),
        axis.text.y = element_text(size = 16, color = "black"),
        legend.title = element_blank(),
        legend.text = element_text(size = 16),
        legend.position = c(0.15,0.95),
        legend.background = element_blank(),
        strip.text = element_blank(),
        strip.background = element_blank(),
        panel.border = element_blank()) +
  guides(fill = guide_legend(nrow = 2)) +
  coord_cartesian(clip = 'off', ylim = c(0,33)) +
  annotation_custom(grid::rectGrob(gp = grid::gpar(fill = NA))) +
  annotate(geom = "text", x = as.Date("2021-06-15", "%Y-%m-%d"), y = -8, label = 2021, size = 6) +
  facet_grid(Location~var_air_water)

# This adds the text to the corresponding figures
dat_text1 <- data.frame(
  label = c("(a","(b"),
  Location = c('Site 1','Site 2'),
  x = c(as.Date("2021-12-01", "%Y-%m-%d"),
        as.Date("2021-12-01", "%Y-%m-%d")),
  y = c(32,32))

p1 <- p1 + geom_text(
  data    = dat_text1,
  mapping = aes(x = x, y = y, label = label,
                hjust   = 0,
                vjust   = 1),
  size = 5)

# This creates the second column of figures
p2 <- df1 %>%
  mutate(var_air_water = ## Here is the new variable
           if_else(Variable %in% c("Air", "Water"), 
                   true = "Air & Water", 
                   false = Variable)) %>%
  subset(!var_air_water == c('Air & Water'),) %>%
  ggplot() +
  geom_line(aes(x = Date, y = Temperature, group = Variable, color = Variable)) +
  scale_color_manual(values = "black") +
  scale_x_date(date_breaks = "2 month",
               date_labels = "%b",
               expand = c(0, 0)) +
  scale_y_continuous(breaks = seq(0,12,2)) +
  labs(x = NULL,
       y = expression(paste(Delta~" Temperature (  ",  degree, "C)"))) +
  theme_bw() +
  theme(plot.margin = unit(c(0, 1, 2, 0), "lines"),
        panel.grid = element_blank(),
        text = element_text(size = 16),
        axis.text.x = element_text(size = 16, color = "black", angle = 90, vjust = 0.5, hjust = 1),
        axis.text.y = element_text(size = 16, color = "black"),
        legend.position = 'none',
        strip.background = element_rect(fill = "gray80"),
        strip.background.x = element_blank(),
        strip.text.x = element_blank(),
        strip.text.y = element_text(size = 16)) +
  guides(fill = guide_legend(nrow = 2)) +
  coord_cartesian(clip = 'off', ylim = c(0,12)) +
  annotation_custom(grid::rectGrob(gp = grid::gpar(fill = NA))) +
  annotate(geom = "text", x = as.Date("2021-06-15", "%Y-%m-%d"), y = -3, label = 2021, size = 6) +
  facet_grid(Location~var_air_water)

# Like above, this adds the text to the corresponding figures
dat_text2 <- data.frame(
  label = c("Pos. = Air > Water", "Neg. = Water > Air", "(c","(d"),
  Location = c('Site 1','Site 1','Site 1','Site 2'),
  x = c(as.Date("2021-01-15", "%Y-%m-%d"),
        as.Date("2021-01-15", "%Y-%m-%d"),
        as.Date("2021-12-01", "%Y-%m-%d"),
        as.Date("2021-12-01", "%Y-%m-%d")),
  y = c(12,11,12,12))

p2 <- p2 + geom_text(
  data    = dat_text2,
  mapping = aes(x = x, y = y, label = label,
                hjust   = 0,
                vjust   = 1,
                size = 10),
  size = 5)

# width = 1200 height = 900
p1 + p2 + plot_layout(ncol = 2)

在此处输入图像描述

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM