Построение небольших кратных с циклом for в R
Я пытаюсь построить карту с сеткой небольших кратных чисел, которая показывает ураганы / тропические штормы, которые пересекались с Флоридой с 1900 года. Я использовал некоторые пространственные запросы для подбора базы данных всех атлантических штормов для этого проекта.
Сейчас я строю линейный шейп-файл из моего ограниченного количества треков ураганов поверх полигонов штата Флорида, некоторых смежных штатов, нескольких крупных городов во Флориде и, конечно, озера Окичоби. Вот простой код:
library(maptools)
library(gdata)
library(RColorBrewer)
setwd("~/hurricanes")
# read shapefiles
florida <- readShapePoly("florida.shp")
south <- readShapePoly("south.shp")
hurricanes <- readShapeLines("hurricanes-florida.shp")
cities <- readShapePoints("cities.shp")
lakes <- readShapePoly("lakes.shp")
# miami, orlando and tallahassee (in FL)
cities <- subset(cities, ST == "FL")
# don't need ALL the 'canes
hurricanes1900 <- subset(hurricanes, Season >= 1900)
mycolors <- brewer.pal(5, "YlOrRd")
pdf(file = "hurricanemaps.pdf", ,width=8,height=20)
par(mfrow=c(15,5), mar=c(1,1,1,1))
for(i in 1:nrow(hurricanes1900))
{
plot(south, col="#e6e6e6", border = "#999999")
plot(florida, col="#999999", border = "#999999", add = TRUE)
plot(lakes, col="#ffffff", border = "#999999", add = TRUE)
plot(cities, pch=10, cex=.1,col="#000000", bg="#e38d2c", lwd=1, add = TRUE)
plot(hurricanes1900[i,], col = mycolors[cut(hurricanes$MAX_Wind_W, breaks = 5)],
lwd=3, add = TRUE); title(hurricanes1900$Title[i])
}
dev.off()
Три большие проблемы, с которыми я сталкиваюсь:
1) Цикл дает мне карту каждого шторма. Я бы предпочел, чтобы код создавал карту Флориды / Юга в сетке для каждого года (даже в те годы без штормов) и всех штормов за этот год, предпочтительно с метками.
2) Я хотел бы установить цвета для скорости ветра среди ВСЕХ штормов, а не только в каждом конкретном ряду петли. Таким образом, сильные штормы (как Эндрю в 1992 году) выглядят темнее, даже когда они являются единственными штормами года. Возможно, я смогу решить эту проблему путем перекодирования категориальной (H1, H2 и т. Д.) Переменной, которая может быть соответственно стилизована.
3) Предполагая, что я могу понять № 1, у меня проблемы с получением меток для рендеринга на каждом пути шторма. Документация maptools не очень хорошая.
Как бы то ни было, вот вывод (заголовок представляет собой объединение двух полей в шейп-файле):
Настоящая проблема № 1. Заранее спасибо за вашу помощь.
1 ответ
Поскольку нет воспроизводимых данных, я собрал некоторые данные для этой демонстрации. Пожалуйста, предоставьте минимальные воспроизводимые данные для пользователей SO в следующий раз. Это поможет вам получить больше помощи.
То, чего вы хотите достичь, можно сделать с помощью ggplot2. Если вы хотите нарисовать карту для каждого года, вы можете использовать facet_wrap()
, Если вы хотите добавить цвета на основе ветра, вы можете сделать это в aes()
когда вы рисуете пути. Если вы хотите добавить имена ураганов, вы можете использовать пакет ggrepel, который позволяет с легкостью предоставлять аннотации. Обратите внимание, что если вы хотите рисовать плавные контуры, вам потребуется обработка данных.
library(stringi)
library(tibble)
library(raster)
library(ggplot2)
library(ggthemes)
library(ggrepel)
library(RColorBrewer)
library(data.table)
# Get some data. Credit to hmbrmstr for a few lines in the following code.
mylist <- c("http://weather.unisys.com/hurricane/atlantic/2007H/BARRY/track.dat",
"http://weather.unisys.com/hurricane/atlantic/2007H/TEN/track.dat",
"http://weather.unisys.com/hurricane/atlantic/2006H/ERNESTO/track.dat",
"http://weather.unisys.com/hurricane/atlantic/2006H/ALBERTO/track.dat")
temp <- rbindlist(
lapply(mylist, function(x){
foo <- readLines(x)
foo <- read.table(textConnection(gsub("TROPICAL ", "TROPICAL_",
foo[3:length(foo)])),
header=TRUE, stringsAsFactors=FALSE)
year <- stri_extract_first(str = x, regex = "[0-9]+")
name <- stri_extract_first(str = x, regex = "[A-Z]{2,}")
cbind(foo, year, name)
}
))
### Add a fake row for 2017
temp <- temp %>%
add_row(ADV = NA, LAT = NA, LON = NA, TIME = NA, WIND = NA,
PR = NA, STAT = NA, year = 2017, name = NA)
### Prepare a map
usa <- getData('GADM', country = "usa", level = 1)
mymap <- subset(usa, NAME_1 %in% c("Florida", "Arkansas", "Louisiana",
"Alabama", "Georgia", "Tennessee",
"Mississippi",
"North Carolina", "South Carolina"))
mymap <- fortify(mymap)
# Create a data.table for labeling hurricanes later.
label <- temp[, .SD[1], by = name][complete.cases(name)]
g <- ggplot() +
geom_map(data = mymap, map = mymap,
aes(x = long, y = lat, group = group, map_id = id),
color = "black", size = 0.2, fill = "white") +
geom_path(data = temp, aes(x = LON, y = LAT, group = name, color = WIND), size = 1) +
scale_color_gradientn(colours = rev(brewer.pal(5, "Spectral")), name = "Wind (mph)") +
facet_wrap(~ year) +
coord_map() +
theme_map() +
geom_text_repel(data = label,
aes(x = LON, y = LAT, label = name),
size = 2,
force = 1,
max.iter = 2e3,
nudge_x = 1,
nudge_y = -1) +
theme(legend.position = "right")