Как динамически настроить цвет фона графика в ggplot2 в зависимости от высоты солнца?

Я создал анимированный график в ggplot2, который визуализирует GPS-треки дневных видов с течением времени. Чтобы улучшить визуализацию, я хотел бы наложить полупрозрачный слой, который динамически меняется в зависимости от того, день сейчас или ночь. Я не хочу использовать статические значения, а хочу использовать фактическую высоту солнца относительно горизонта. Я дополнил свой набор данных положениями солнца, используя пакет suncalc. Воспроизводимый пример с фиктивными данными можно найти ниже. Кто-нибудь, кто может помочь мне в правильном направлении?

library(ggplot2)
library(gganimate)
library(sf)
library(suncalc)
library(ggspatial)  
library(gifski)
library(prettymapr)


#  sample data
set.seed(123)
gps_data_sf <- data.frame(
  IMEI = rep(35664665, 300),  
  Pick.Time = seq.POSIXt(as.POSIXct("2024-08-13 00:00:00"), by = "15 mins", length.out = 300),
  Longitude = runif (300, 2.7, 2.8),
  Latitude = runif (300, 51.1, 51.2),
  Bird = rep("Bird A", 300)
)

# add sun height
gps_data_sf$sunheight <- mapply(function(lat, lon, time) {
  sun_position <- getSunlightPosition(date = time, lat = lat, lon = lon)
  return(sun_position$altitude) 
}, gps_data_sf$Latitude, gps_data_sf$Longitude, gps_data_sf$Pick.Time)

# Convert to sf 
gps_data_sf <- st_as_sf(gps_data_sf, coords = c("Longitude", "Latitude"), crs = 4326)

# animate
animated_plot <- ggplot() +
  annotation_map_tile(type = "osm", zoom = 12) + 
  geom_sf(data = gps_data_sf, aes(geometry = geometry, color = Bird, group = Bird), size = 5, alpha = 0.8) +
  labs(
    title = "Movement",
    subtitle = "Time: {frame_time}",
    x = "Longitude",
    y = "Latitude"
  ) +
  transition_time(Pick.Time) + 
  ease_aes('linear')

# Render
animate(animated_plot, nframes = 100, fps = 10, width = 800, height = 600, renderer = gifski_renderer())


library(gifski) необходим, поэтому отредактируйте его. Вы уверены, что ваш код работает без проблем? > Error in png_dim(): ! Provided file
Friede 16.08.2024 10:03

Спасибо за это. У меня код работает без проблем.

reinoud 16.08.2024 12:52

Возможно, вам придется установить пакет Prettymapr.

Michiel Duvekot 16.08.2024 13:40

Проголосовали за закрытие.

Friede 16.08.2024 13:42

У меня не возникло проблем с запуском кода, reinoud. Пакет gifski должен быть установлен, но вам не нужно вызывать эту библиотеку. Он вызывается ggplot2, когда вы запускаете вызов анимации с использованием средства рендеринга по умолчанию. Я не знаю, почему этот вопрос был закрыт.

Kat 17.08.2024 02:30
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
3
5
68
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Использование geom_rect вместе с scale_fill_gradient может создать тот образ, которого вы пытаетесь достичь.

Сначала я переместил данные и группировку в ggplot, чтобы их можно было унаследовать geom_rect.

При вызове geom_rect с помощью НФ, если вы хотите заполнить весь сюжет, вы можете использовать -Inf для Inf. Я произвольно использовал альфу 0,4 для этого слоя.

Наконец, с помощью scale_fill_gradient мы создали высокий и низкий цветовой градиент для имитации солнца. (Я использовал черный и желтый цвета для ночи и дня.)

Вызов geom_sf такой же, как и в вашем вопросе, за исключением аргументов, которые были перенесены в ggplot() (data и group).

# animate
animated_plot <- ggplot(gps_data_sf, group = Bird) +   # move data and grouping to ggplot
  annotation_map_tile(type = "osm", zoom = 12) + 
  geom_sf(aes(geometry = geometry, color = Bird),
          size = 5, alpha = 0.8) +
  geom_rect(xmin = -Inf, xmax = Inf, ymin = -Inf, ymax = Inf,  # add color space
            aes(fill = sunheight), alpha = .4) +
  scale_fill_gradient(low = "black", high = "yellow") +        # specify colors
  labs(
    title = "Movement", subtitle = "Time: {frame_time}",
    x = "Longitude", y = "Latitude") +
  transition_time(Pick.Time) + ease_aes('linear')

Несколько изображений, чтобы вы могли увидеть, как меняется наложение градиента (это 3 часа ночи и 10 утра)

Это именно то, что я искал, спасибо!

reinoud 17.08.2024 08:52

Другие вопросы по теме