Вопрос или проблема
Я пытаюсь затенить фон моего графика ggplot так, чтобы утренние часы были более светлыми, а вечерние – темными.
Вот мои данные:
date time dosage ww Group id no3 po4 ToD hour_shade
1 2024-09-30 11:20:00 11H 20M 0S full 5 A A5-1 8.9 3.8 AM gray90
2 2024-09-30 11:20:00 11H 20M 0S full 5 A A5-2 12.8 4.0 AM gray90
3 2024-09-30 11:20:00 11H 20M 0S full 5 A A5-3 10.4 3.8 AM gray90
4 2024-09-30 11:20:00 11H 20M 0S half 5 B B5-1 5.2 2.0 AM gray90
5 2024-09-30 11:20:00 11H 20M 0S half 5 B B5-2 5.2 1.9 AM gray90
6 2024-09-30 11:20:00 11H 20M 0S half 5 B B5-3 5.2 1.8 AM gray90
Вот код для моего графика:
nitratePlot = lt2 %>% filter(!is.na(ToD)) %>%
ggplot() +
aes(x = date, y = no3) +
geom_point(shape = "circle", size = 1.5) +
labs(x = "Дата", y = "[NO3]") +
theme_classic() +
facet_wrap(vars(dosage)) +
scale_x_datetime(date_breaks = "1 день",
expand = c(0.05, 0.05)) +
geom_rect(aes(xmin = as.POSIXct("2024-9-29 11:20:00"), xmax = as.POSIXct("2024-10-11 0:0:00"), ymin = -Inf, ymax = Inf,
fill = hour_shade),
alpha = 0.1) +
geom_point()+
scale_fill_identity() +
theme(axis.text.x = element_text(angle = 45, vjust = 0.5, hjust=1))
Почему-то он просто затеняет всю среднюю часть в Gray60: (https://i.sstatic.net/v83u61Vo.png).
Я думаю, это может быть связано с тем, что моя ось x представляет собой дату, а не время, но не знаю, есть ли способ это обойти. Спасибо!
Ответ или решение
Когда вы пытаетесь затенить фон вашего графика в ggplot, важно правильно задать параметры для функций, которые управляют этим процессом. Давайте разберемся подробнее, почему данный код затеняет всю область графика, а не только выделенные области AM и PM.
Анализ вашей проблемы
-
Область затенения:
Вы используетеgeom_rect()
, чтобы закрасить область графика. Ваша текущая реализация задает значенияxmin
,xmax
,ymin
иymax
как:geom_rect(aes(xmin = as.POSIXct("2024-9-29 11:20:00"), xmax = as.POSIXct("2024-10-11 0:0:00"), ymin = -Inf, ymax = Inf, fill = hour_shade), alpha = 0.1)
Здесь
ymin = -Inf
иymax = Inf
фактически создают прямоугольник, который растягивается на всю высоту графика, что и приводит к затенению всю область. -
Форматирование времени:
Поскольку ваша ось абсцисс представляет собой даты, а не просто время, это также может приводить к трудностям. Убедитесь, что у вас есть соответствующие временные метки для AM и PM, чтобы вы могли задать ха классификации.
Рекомендации по исправлению
Чтобы исправить эту ситуацию и затенить только области AM и PM, вам нужно выполнить несколько изменений:
-
Задать правильные временные рамки:
Используйтеgeom_rect()
дважды: один для AM (светлый оттенок) и один для PM (темный оттенок). Пример:nitratePlot = lt2 %>% filter(!is.na(ToD)) %>% ggplot() + aes(x = date, y = no3) + geom_point(shape = "circle", size = 1.5) + labs(x = "Дата", y = "[NO3]") + theme_classic() + facet_wrap(vars(dosage)) + scale_x_datetime(date_breaks = "1 day", expand = c(0.05, 0.05)) + # Затенение для AM geom_rect(aes(xmin = as.POSIXct("2024-09-30 00:00:00"), xmax = as.POSIXct("2024-09-30 12:00:00"), ymin = -Inf, ymax = Inf), fill = "gray90", alpha = 0.1) + # Затенение для PM geom_rect(aes(xmin = as.POSIXct("2024-09-30 12:00:00"), xmax = as.POSIXct("2024-10-01 00:00:00"), ymin = -Inf, ymax = Inf), fill = "gray60", alpha = 0.1) + geom_point() + theme(axis.text.x = element_text(angle = 45, vjust = 0.5, hjust=1))
-
Контроль областей затенения:
Убедитесь, что временные метки правильно представляют области AM и PM. В вышеуказанном коде AM — это первая половина дня, а PM — вторая.
Заключение
Корректируя область затенения, используя два отдельных вызова geom_rect()
, вы сможете достичь необходимого визуального результата с различие по времени для AM и PM. Убедитесь, что весь код согласуется с форматом временных данных, чтобы избежать дальнейших проблем с представлением. Если возникнут дополнительные вопросы или потребуется дополнительная помощь, пожалуйста, не стесняйтесь обращаться за поддержкой.