Как мне добавить вторую переменную точки на анимированные карты R?

#r #animation #maps

#r #Анимация #Карты

Вопрос:

Я новичок в анимации данных в R. Я пытаюсь анимировать 2 переменные (уровни NO2 и номера транспортных средств) с почасовыми показаниями между блокировкой и предварительной блокировкой на одной карте, чтобы она показывала изменение обеих переменных по местоположению (для 3 датчиков) по дням и часам за апрель 2019 и апрель 2020. Я могу использовать одну переменную (показанную в коде) и даже изменить форму точки для представления трафика в час пик), но у меня возникают проблемы с получением второй переменной (транспортные средства) для работы. Идея состоит в том, чтобы показать, как меньший трафик в режиме карантина снижает уровни NO2 (хотя регрессия для этого меньше, чем можно было бы ожидать).

Я знаю, что данные для карантина будут на 2 дня отличаться от прошлогодних (високосный год), но в настоящее время это только для учебных целей, поэтому я пока не пытаюсь загружать больше данных, чтобы попытаться исправить это. Я хотел бы знать, как мне получить данные о транспортных средствах для отображения одновременно с данными NO2? Я попытался добавить еще geom_point одну и слегка подтолкнуть ее, чтобы они не перекрывались, но это не сработало — я не думаю, что у меня может быть 2 geom_points на одной карте. Сейчас я пробую geom_jitter для транспортных средств и могу заставить его менять цвет, но не менять размер. Кажется, что у вас может быть только один scale_size для каждой карты. Есть ли способ обойти это?

Отредактировано, чтобы использовать dput для добавления данных и показать еще один пример того, что я пробовал — надеюсь, теперь я все исправил. Отредактировано еще раз, чтобы быть более понятным и добавить код для единственной переменной, которая работает

 structure(list(Location = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L, 3L, 3L, 
3L, 3L), .Label = c("Coast_Road", "Gosforth", "TyneBridge"), class = "factor"), 
    Date = structure(c(1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 1L, 1L, 
    1L, 1L, 2L, 2L, 2L, 2L, 1L, 1L, 1L, 2L, 1L, 2L, 2L, 2L), .Label = c("1/4/2019", 
    "1/4/2020", "10/4/2019", "10/4/2020", "11/4/2019", "11/4/2020", 
    "12/4/2019", "12/4/2020", "13/4/2019", "13/4/2020", "14/4/2019", 
    "14/4/2020", "15/4/2019", "15/4/2020", "16/4/2019", "16/4/2020", 
    "17/4/2019", "17/4/2020", "18/4/2019", "18/4/2020", "19/4/2019", 
    "19/4/2020", "2/4/2019", "2/4/2020", "20/4/2019", "20/4/2020", 
    "21/4/2019", "21/4/2020", "22/4/2019", "22/4/2020", "23/4/2019", 
    "23/4/2020", "24/4/2019", "24/4/2020", "25/4/2019", "25/4/2020", 
    "26/4/2019", "26/4/2020", "27/4/2019", "27/4/2020", "28/4/2019", 
    "28/4/2020", "29/4/2019", "29/4/2020", "3/4/2019", "3/4/2020", 
    "30/4/2019", "30/4/2020", "4/4/2019", "4/4/2020", "5/4/2019", 
    "5/4/2020", "6/4/2019", "6/4/2020", "7/4/2019", "7/4/2020", 
    "8/4/2019", "8/4/2020", "9/4/2019", "9/4/2020"), class = "factor"), 
    Date2 = c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
    1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), Hour = c("04", 
    "03", "02", "01", "04", "03", "01", "02", "04", "01", "02", 
    "03", "04", "03", "02", "01", "03", "04", "02", "04", "01", 
    "03", "02", "01"), Day = structure(c(2L, 2L, 2L, 2L, 7L, 
    7L, 7L, 7L, 2L, 2L, 2L, 2L, 7L, 7L, 7L, 7L, 2L, 2L, 2L, 7L, 
    2L, 7L, 7L, 7L), .Label = c("Fri", "Mon", "Sat", "Sun", "Thurs", 
    "Tues", "wed"), class = "factor"), Lock = structure(c(2L, 
    2L, 2L, 2L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 1L, 1L, 1L, 1L, 
    2L, 2L, 2L, 1L, 2L, 1L, 1L, 1L), .Label = c("Lockdown", "PreLockdown"
    ), class = "factor"), Rush = structure(c(1L, 1L, 1L, 1L, 
    1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
    1L, 1L, 1L, 1L, 1L), .Label = c("NonRushHour", "RushHour"
    ), class = "factor"), NO2 = c(27.76196, 35.78016, 45.7216, 
    22.2686, 6.23032, 5.7622, 8.53896, 11.8158, 22.16896, 28.5572, 
    24.957, 18.73608, 4.60976, 4.11532, 10.5656, 5.6024, 25.98724, 
    28.00448, 50.7224, 8.65552, 82.8046, 11.8722, 8.4506, 9.3812
    ), Vehicles = c(38L, 54L, 43L, 37L, 20L, 34L, 30L, 41L, 14L, 
    13L, 6L, 10L, 23L, 19L, 18L, 16L, 31L, 43L, 30L, 49L, 35L, 
    30L, 38L, 26L), DateTime = c(1.04, 1.03, 1.02, 1.01, 1.04, 
    1.03, 1.01, 1.02, 1.04, 1.01, 1.02, 1.03, 1.04, 1.03, 1.02, 
    1.01, 1.03, 1.04, 1.02, 1.04, 1.01, 1.03, 1.02, 1.01), Lon = c(-1.5662, 
    -1.5662, -1.5662, -1.5662, -1.5662, -1.5662, -1.5662, -1.5662, 
    -1.6199, -1.6199, -1.6199, -1.6199, -1.6199, -1.6199, -1.6199, 
    -1.6199, -1.606, -1.606, -1.606, -1.606, -1.606, -1.606, 
    -1.606, -1.606), Lat = c(54.9944, 54.9944, 54.9944, 54.9944, 
    54.9944, 54.9944, 54.9944, 54.9944, 55.0071, 55.0071, 55.0071, 
    55.0071, 55.0071, 55.0071, 55.0071, 55.0071, 54.968, 54.968, 
    54.968, 54.968, 54.968, 54.968, 54.968, 54.968)), row.names = c(1L, 
2L, 3L, 5L, 1074L, 1080L, 1331L, 1430L, 1481L, 1501L, 1502L, 
1605L, 2198L, 2202L, 2204L, 2205L, 2966L, 2968L, 2972L, 3315L, 
3340L, 3441L, 3442L, 3443L), class = "data.frame")
 

Кодовый блок:

 library(gganimate) library(OpenStreetMap) library(ggplot2) library(maps)

#set lat and long for the size of the map (top left and bottom right coordinates)
 
LAT1 =  54.962130 ; LAT2 = 55.018427 LON1 = -1.556871 ; LON2 =
-1.652677
 
map <- openmap(c(LAT2,LON1), c(LAT1,LON2), zoom = NULL)

map.latlon <- openproj(map) 

My_Theme = theme(   plot.title = element_text(size = 30),  
legend.position = "right",    legend.text = element_text(color =
"black", size = 18),   legend.title = element_text(size = 20),  
axis.title = element_text(size = 25),   axis.text = element_text(size = 20),   strip.text = element_text(face="bold", size=25,lineheight=5.0),   strip.background =
element_rect(fill="lightblue", colour="black", size=1))

OSMap <-  OpenStreetMap::autoplot.OpenStreetMap(map.latlon)  
  geom_label(data=pol5, aes(x=Lon ,y=Lat, label=Location, fontface=7), hjust=1.3, vjust=0, size=7)  
  geom_point(aes(x = Lon, y = Lat, size = NO2,  shape = Rush),
             data = pol5, color="red")   
  
  scale_size_continuous(range = c(4, 30), breaks = c(0, 50, 100, 150, 200))  
  labs(size = 'NO2')   
  facet_wrap(~Lock)   
  My_Theme     
  labs(title = "Date and Time  {closest_state}")  
  transition_states(DateTime, transition_length = 3, state_length = 1)

animate(OSMap , nframes = 100, fps=12, width = 1600, height = 1000, start_pause= 20, end_pause = 30, rewind = TRUE)

 

Комментарии:

1. Добро пожаловать в SO! Вы правы в том, что не можете прикрепить файл, но вы можете опубликовать готовый для копирования и вставки фрагмент dput(pol2) (в идеале, только столько pol2 , сколько необходимо для демонстрации проблемы). Это, а также пример кода, который у вас уже есть, помогут вам получить ответ как можно быстрее.

2. ах, спасибо — это полезно знать. Итак, мои данные таковы

3. упс, извиняюсь за предыдущий комментарий — ошибка новичка. Спасибо за помощь — сейчас я отредактировал свой пост (надеюсь, правильно) и был бы признателен за любую предложенную помощь.

4. Данные выглядят великолепно — отлично загружаются с моей стороны. Однако я получаю некоторые ошибки с остальной частью кода; можете ли вы запустить его самостоятельно со своей стороны и посмотреть, что нужно скорректировать? Скорее всего, это опечатки, но я не могу восстановить все необходимые исправления.

5. Спасибо, что ответили. Я повторно запустил его код, и кажется, что ему нужен бит после scale_color_manual ( latb(title= на новой строке, но я получаю следующее сообщение об ошибке Ошибка в continuous_scale(эстетика, «градиент», seq_gradient_pal(низкий, : неиспользуемые аргументы (цвет = «синий», альфа= 1) Кроме того: Предупреждающее сообщение: игнорирование неизвестной эстетики: накопительный — код выполняется, но результирующая карта имеет неправильную легенду, в которой синие точки отображаются как значения NO2, а не транспортные средства. Я не уверен, связано ли это с тем, что я неправильно установил легенды, или я неправильно понимаю дрожание.

Ответ №1:

Один из способов получить обе точки на карте — это повернуть фрейм данных: получить одну строку на «меру», где «мерой» является либо NO2, либо количество транспортных средств. Вот карта с NO2 красным цветом и транспортными средствами синего цвета; транспортные средства немного перемещены на восток, чтобы точки не перекрывались.

 OSMap <-  OpenStreetMap::autoplot.OpenStreetMap(map.latlon)   
  geom_label(data = pol5,
             aes(x = Lon, y = Lat, label = Location),
             fontface = 7, hjust = 1.3, vjust = 0, size = 7)  
  geom_point(data = pol5 %>%
               dplyr::select(DateTime, Lon, Lat, NO2, Vehicles, Rush, Lock) %>%
               pivot_longer(cols = c("NO2", "Vehicles"), names_to = "measure") %>%
               mutate(Lon = Lon   ifelse(measure == "Vehicles", 0.005, 0)),
             aes(x = Lon, y = Lat, color = measure, fill = measure,
                 size = value, shape = Rush))  
  scale_size_continuous(range = c(4, 30), breaks = c(0, 50, 100, 150, 200),
                        guide = F)  
  labs(size = 'NO2 or Vehicles')   
  facet_wrap(~ Lock)   
  My_Theme     
  labs(title = "Date and Time  {closest_state}")  
  transition_states(DateTime, transition_length = 3, state_length = 1)
 

введите описание изображения здесь

Вероятно, вам потребуется больше доработок, чтобы получить именно то поведение, которое вы хотите. Например, как вы уже отметили, не имеет смысла иметь одинаковый масштаб для NO2 и транспортных средств; они даже не используют одинаковые единицы измерения. Пока все работает нормально, потому что значения двух мер занимают одинаковый диапазон, но это не обязательно было бы правдой, если бы вы хотели добавить какую-то другую меру. Я бы, вероятно, взломал вещи, нормализовав значения внутри каждой меры, чтобы они попадали в диапазон [0, 1], где 0 представляет наименьшее наблюдаемое значение, а 1 — наибольшее. Я не уверен, можно ли было бы показать пользовательскую легенду с двумя разными масштабами размеров; Я знаю, что это непросто по ggplot2 дизайну. Если нет, я мог бы полностью отключить масштаб размера и добавить метки к точкам; вот примерная версия того, как это может выглядеть:

 OSMap <-  OpenStreetMap::autoplot.OpenStreetMap(map.latlon)   
  geom_label(data = pol5,
             aes(x = Lon, y = Lat, label = Location),
             fontface = 7, hjust = 1.3, vjust = 0, size = 7)  
  geom_point(data = pol5 %>%
               dplyr::select(DateTime, Lon, Lat, NO2, Vehicles, Rush, Lock) %>%
               pivot_longer(cols = c("NO2", "Vehicles"), names_to = "measure") %>%
               mutate(Lon = Lon   ifelse(measure == "Vehicles", 0.005, 0)),
             aes(x = Lon, y = Lat, color = measure, fill = measure,
                 size = value, shape = Rush))  
  geom_text(data = pol5 %>%
              dplyr::select(DateTime, Lon, Lat, NO2, Vehicles, Rush, Lock) %>%
              pivot_longer(cols = c("NO2", "Vehicles"), names_to = "measure") %>%
              mutate(Lon = Lon   ifelse(measure == "Vehicles", 0.005, 0),
                     value = round(value)),
            aes(x = Lon, y = Lat, label = value))  
  scale_size_continuous(range = c(4, 30), breaks = c(0, 50, 100, 150, 200),
                        guide = F)  
  facet_wrap(~ Lock)   
  My_Theme     
  labs(title = "Date and Time  {closest_state}")  
  transition_states(DateTime, transition_length = 3, state_length = 1)
 

введите описание изображения здесь