Почему затенённая область на моем графике затеняет всю область, а не только области AM и PM?

Вопрос или проблема

Я пытаюсь затенить фон моего графика 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.

Анализ вашей проблемы

  1. Область затенения:
    Вы используете 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 фактически создают прямоугольник, который растягивается на всю высоту графика, что и приводит к затенению всю область.

  2. Форматирование времени:
    Поскольку ваша ось абсцисс представляет собой даты, а не просто время, это также может приводить к трудностям. Убедитесь, что у вас есть соответствующие временные метки для AM и PM, чтобы вы могли задать ха классификации.

Рекомендации по исправлению

Чтобы исправить эту ситуацию и затенить только области AM и PM, вам нужно выполнить несколько изменений:

  1. Задать правильные временные рамки:
    Используйте 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))
  2. Контроль областей затенения:
    Убедитесь, что временные метки правильно представляют области AM и PM. В вышеуказанном коде AM — это первая половина дня, а PM — вторая.

Заключение

Корректируя область затенения, используя два отдельных вызова geom_rect(), вы сможете достичь необходимого визуального результата с различие по времени для AM и PM. Убедитесь, что весь код согласуется с форматом временных данных, чтобы избежать дальнейших проблем с представлением. Если возникнут дополнительные вопросы или потребуется дополнительная помощь, пожалуйста, не стесняйтесь обращаться за поддержкой.

Оцените материал
Добавить комментарий

Капча загружается...