[英]ggplot2: how to extend y-axis labels across stacked figures
我有一个来自两个位置(即Site 1
和Site 2
)的一年的每日平均温度观测数据框。 三个温度变量是:
Air
Water
Difference
= 空气 - 水我想生成一个四面板图,其中顶行和底行分别是Site 1
和Site 2
,左列显示Air
和Water
,右列显示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.