2015-07-01 3 views
7

Я пытаюсь построить с ggplot2 трек птицы вокруг Антарктики. Пока я получил карту, проецируемую в полярных координатах, мне также удалось правильно построить точки трека, и я почти правильно их связываю, но ... Поскольку трасса пересекает международный DATE & TIME line, ggplot2 не может правильно установить ссылку 2 точки по обе стороны линии. Итак, я ищу способ заставить ggplot связать точки в непрерывном режиме.Как добавить размер времени в полярных координатах в R?

Вот мой набор данных:

Data => 
ID Date  Time A1 Lat. Long. 
10 12.9.2008 22:00 1 21.14092 70.98817 
10 12.9.2008 22:20 1 21.13031 70.97592 
10 12.9.2008 22:40 2 21.13522 70.97853 
10 12.9.2008 23:00 1 21.13731 70.97817 
10 12.9.2008 23:20 3 21.14197 70.97981 
10 12.9.2008 23:40 1 21.14156 70.98158 
10 12.9.2008 23:40 1 21.14156 70.98158 
10 13.9.2008 00:00 2 21.14150 70.98478 
10 13.9.2008 00:20 3 21.14117 70.98803 
10 13.9.2008 00:40 1 21.14117 70.98803 
10 13.9.2008 01:00 2 21.14117 70.98803 

.... 

ID является птичье ID.

UPDATE с помощью Nick K код

Вот мой исходный граф без измерения времени и линии

south_map <- map_data("world") %>% group_by(group) 
set.seed(123) 

track_df2 <- new_df2 

long_diff <- diff(new_df2$Long) 
long_diff[long_diff < -180] <- long_diff[long_diff < -180] + 360 
long_diff[long_diff > 180] <- long_diff[long_diff > 180] - 360 
track_df2$Longitude <- cumsum(c(new_df2$Long[1], long_diff)) 

ggplot(track_df2, aes(x = track_df2$Long, y = track_df2$Lat)) + 
geom_polygon(aes(group = a3_id), data = south_map, colour = "grey", fill = "gainsboro") + 
geom_point(aes(colour = factor(a3_id)), size = 2) 

A1 определяет то, что птица в настоящее время делает.

enter image description here

+1

Просто соедините точки на основе отсортированного времени ? – Vlo

+1

согласен с @Vlo, я думаю, вам нужно просто преобразовать времена. аккуратная проблема –

+1

@VIo Я тебя не понял. Можете ли вы привести мне пример или объяснить мне? – ayush

ответ

13

Вам не кажется, на самом деле использовать время в вашем участке, но проблема заключается в долгот обтекание -180/180. Это можно решить, используя coord_map, а не coord_polar и гарантируя, что долготы не обертываются.

Загрузка пакетов и генерируют выборочные данные

library("ggplot2") 
library("dplyr") 
south_map <- map_data("world") %>% group_by(group) %>% filter(min(lat) <= -20) 

set.seed(123) 
track <- data.frame(long = cumsum(c(210, 
            unlist(lapply(c(1, -1), function(x) { 
             rnorm(50, x * 4, 4) 
             })))) %% 360 - 180, 
        lat = cumsum(c(-50, rnorm(100, 0.4, 2))), 
        A1 = sample(1:3, 101, replace = TRUE)) 

Убедитесь, что координаты не обернуть вокруг:

track_new <- track 
long_diff <- diff(track$long) 
long_diff[long_diff < -180] <- long_diff[long_diff < -180] + 360 
long_diff[long_diff > 180] <- long_diff[long_diff > 180] - 360 
track_new$long <- cumsum(c(track$long[1], long_diff)) 

Участок с использованием aziequidistant проекции. Обратите внимание, что это предполагает Северный полюс в центре, поэтому широты перевернуты, а затем скорректированы с помощью шкалы.

ggplot(track_new, aes(x = long, y = -lat)) + 
    geom_polygon(aes(group = group), data = south_map, colour = "grey", fill = "gainsboro") + 
    coord_map("azequidistant") + 
    geom_point(aes(colour = factor(A1)), size = 2) + 
    geom_path(colour = "grey", size = 1) + 
    scale_x_continuous(breaks = NULL) + 
    scale_y_continuous("latitude", breaks = 25 * 0:3, labels = -25 * 0:3) 

Заключительный участок:

Bird plot

Просто для интереса, я думал, что это было бы интересно, чтобы произвести анимацию этого изображения. Вот код, чтобы сделать это:

track_new$alpha <- 1 
# Setup longitude labels 

long_labels <- data.frame(long = 45 * -3:4, lat = -22.5) 
long_labels$label <- long_labels$long 
long_labels$label[8] <- "\U00B1 180" 
long_labels$angle <- long_labels$long + 67.5 + 180 * (long_labels$long >= 45) 

# Set up the basic plot 
p <- ggplot(track_new, aes(x = long, y = -lat)) + 
    geom_polygon(aes(group = group), data = south_map, colour = "grey", fill = "gainsboro") + 
    coord_map("azequidistant", ylim = c(20, 90)) + 
    geom_point(aes(colour = A1, alpha = alpha), size = 2) + 
    geom_path(aes(alpha = alpha), colour = "grey", size = 1) + 
    scale_x_continuous(breaks = NULL) + 
    scale_y_continuous("latitude", breaks = 22.5 * 0:3, labels = -22.5 * 0:3) + 
    scale_alpha_identity(guide = "none") + 
    geom_text(aes(label = label, angle = angle), 
      data = long_labels, colour = "dark blue", alpha = 0.5, size = 4) 

# Produce the animation 
p$data$alpha <- 0 
for(i in 1:(nrow(track_new) + 10)) { 
    p$data$alpha <- pmax(p$data$alpha - 0.1, 0) 
    if (i <= nrow(track_new)) { 
    p$data$alpha[i] <- 1 
    } 
    png(file.path("BirdPlots", sprintf("BirdPlot%03d.png", i)), width = 1024, height = 1024, res = 100) 
    print(p) 
    dev.off() 
    if (!(i %% 5)) cat(i, "\n") 
} 

# This needs ImageMagick in the system path. For non-Windows systems, you 
# might be better using system rather than shell 
shell(paste("convert", file.path("BirdPlots", "BirdPlot*.png"), 
    file.path("BirdPlots", "BirdPlotAnimation.gif"))) 

И вот результат:

Animation of bird

EDIT Исправленная версия кода Ayush в

track_df2 <- new_df2 

long_diff <- diff(new_df2$Longitude) 
long_diff[long_diff < -180] <- long_diff[long_diff < -180] + 360 
long_diff[long_diff > 180] <- long_diff[long_diff > 180] - 360 
track_df2$Longitude <- cumsum(c(new_df2$Longitude[1], long_diff)) 

track_df2$a3_id <- factor(track_df2$a3_id) 

ggplot(track_df2, aes(x = Longitude, y = -Latitude)) + 
    coord_map("azequidistant", ylim = c(20, 90)) + 
    geom_point(aes(colour = a3_id, alpha = alpha), size = 2) + 
    geom_path(aes(alpha = alpha), colour = "grey", size = 1) + 
    scale_x_continuous(breaks = NULL) + 
    scale_y_continuous(breaks = 22.5 * 0:3, labels = -22.5 * 0:3) + 
    scale_alpha_identity(guide = "none") 
+0

Я добавил анимированную версию, которая создает серию PNG и преобразует их в анимированный GIF. –

+0

Его хорошее решение. Но указанная проблема заключается в добавлении функции даты и времени. Да, я не использовал D & T в своем заговоре, потому что я не могу найти зол для этого. Можете ли вы добавить Time как 3-е измерение, а затем построить результат? Какая проблема, с которой я столкнулся, после 23:59:59 часов сбрасывается на 00:00:00. Следовательно, он создает слои. Я хочу сохранить этот 2D-график в 3D. Можете ли вы решить эту проблему? – ayush

+0

@ayush Я не совсем понимаю, что вы имеете в виду. Вы хотите, чтобы 3D-график рассеялся эффективно, со временем, представленным как высота? Или что-то другое? что ты уже испробовал? Стоит также отметить, что ваши исходные данные были между 70.9 и 71 градусами долготы, поэтому полярная проекция у вас выглядела так. –