Как наложить карту пространственного прогнозирования кригинга на определенную область карты страны в R?

У меня есть почасовой набор данных PM10 для 81 наблюдения с именем "seoul032823". Вы можете загрузить его с Здесь. Я выполнил обычный кригинг для этого набора данных, а также получил пространственную карту для прогнозирования кригинга. Я также могу показать точки данных наблюдений на карте страны. Но я не могу перекрыть карту пространственного прогнозирования кригинга на карте страны.

Что я хочу сделать: я хочу наложить свою карту пространственного прогнозирования на карту Южной Кореи (а не всей Южной Кореи). Область моих интересов - от 37,2 до 37,7 северной широты и от 126,6 до 127,2 восточной долготы. Это означает, что мне нужно обрезать эту область с карты Кореи и наложить на нее карту прогноза. Мне также нужно показать исходные точки данных наблюдений, которые будут соответствовать цвету пространственной карты в соответствии со значениями концентрации. Например, мне нужен такой тип карты:  введите описание изображения здесь

Мой код R для кригинга и отображение точки данных на карте Кореи:

library(sp)
library(gstat)
library(automap)
library(rgdal)
library(e1071)
library(dplyr)
library(lattice)

seoul032823 <- read.csv ("seoul032823.csv")

#plotting the pm10 data on Korea Map
library(ggplot2)
library(raster)

seoul032823 <- read.csv ("seoul032823.csv")
skorea<- getData("GADM", country= "KOR", level=1)
plot(skorea)

skorea<- fortify(skorea)
ggplot()+
  geom_map(data= skorea, map= skorea, aes(x=long,y=lat,map_id=id,group=group),
           fill=NA, colour="black") +
  geom_point(data=seoul032823, aes(x=LON, y=LAT), 
             colour= "red", alpha=0.7,na.rm=T) +
  #scale_size(range=c(2,4))+
  labs(title= "PM10 Concentration in Seoul Area at South Korea",
       x="Longitude", y= "Latitude", size="PM10(microgm/m3)")+
  theme(title= element_text(hjust = 0.5,vjust = 1,face= c("bold")))

# Reprojection
coordinates(seoul032823) <- ~LON+LAT
proj4string(seoul032823) <- "+proj=longlat +datum=WGS84" 
seoul032823 <- spTransform(seoul032823, CRS("+proj=utm +north +zone=52 +datum=WGS84"))

#Creating the grid for Kriging
LON.range <- range(as.integer(seoul032823@coords[,1 ])) + c(0,1)
LAT.range <- range(as.integer(seoul032823@coords[,2 ]))
seoul032823.grid <- expand.grid(LON = seq(from = LON.range[1], to = LON.range[2], by = 1500),
                                LAT = seq(from = LAT.range[1], to = LAT.range[2], by = 1500))
plot(seoul032823.grid)
points(seoul032823, pch= 16,col="red")
coordinates(seoul032823.grid)<- ~LON+LAT
gridded(seoul032823.grid)<- T
plot(seoul032823.grid)
points(seoul032823, pch= 16,col="red")

# kriging spatial prediction map
seoul032823_OK<- autoKrige(formula = PM10~1,input_data = seoul032823, new_data = seoul032823.grid )
pts.s <- list("sp.points", seoul032823, col = "red", pch = 16)
automapPlot(seoul032823_OK$krige_output, "var1.pred", asp = 1,
            sp.layout = list(pts.s), main = " Kriging Prediction")

Я использовал automap пакет для кригинга и ggplot2 для построения карты Кореи.


person Orpheus    schedule 29.03.2016    source источник
comment
Вы предложили награду, но не присудили ее? Ой, черт возьми. :)   -  person oshun    schedule 13.04.2016
comment
Мне правда очень жаль. Я забыл. Я принял твой ответ. что мне делать, чтобы наградить тебя?   -  person Orpheus    schedule 14.04.2016
comment
Не стоит беспокоиться. ТАК автоматически присуждается половина. В любом случае, я надеюсь, что вы исправили остальные косметические изменения, которые хотели.   -  person oshun    schedule 15.04.2016
comment
Спасибо за вашу любезную заботу. На самом деле, я очень стараюсь, но пока не добился успеха. theme_minimal () во многих случаях создает проблемы. кстати, хорошего дня.   -  person Orpheus    schedule 15.04.2016


Ответы (1)


Я не слишком знаком с пространственным анализом, поэтому могут возникнуть проблемы с проекцией.

Во-первых, ggplot2 лучше работает с data.frames, чем с пространственными объектами, согласно этому ответу со ссылкой на Зев Росс. Зная это, мы можем извлечь предсказания кригинга из вашего кригированного пространственного объекта seoul032823_OK. Остальное относительно просто. Вероятно, вам придется исправить маркировку осей долготы / широты и убедиться, что размеры верны на окончательном выходе. (Если вы это сделаете, я могу отредактировать / добавить ответ, чтобы включить эти дополнительные шаги.)

# Reprojection of skorea into same coordinates as sp objects
# Not sure if this is appropriate
coordinates(skorea) <- ~long+lat  #{sp} Convert to sp object
proj4string(skorea) <- "+proj=longlat +datum=WGS84" #{sp} set projection attributes
#{sp} Transform to new coordinate reference system
skorea <- spTransform(skorea, CRS("+proj=utm +north +zone=52 +datum=WGS84")) 

#Convert spatial objects into data.frames for ggplot2
myPoints <- data.frame(seoul032823)
myKorea <- data.frame(skorea)
#Extract the kriging output data into a dataframe.  This is the MAIN PART!
myKrige <- data.frame(seoul032823_OK$krige_output@coords, 
                      pred = seoul032823_OK$krige_output@data$var1.pred)   
head(myKrige, 3)  #Preview the data
#     LON     LAT     pred
#1 290853 4120600 167.8167
#2 292353 4120600 167.5182
#3 293853 4120600 167.1047

#OP's original plot code, adapted here to include kriging data as geom_tile
ggplot()+ theme_minimal() +
  geom_tile(data = myKrige, aes(x= LON, y= LAT, fill = pred)) +
  scale_fill_gradient2(name=bquote(atop("PM10", mu*g~m^-3)), 
                       high="red", mid= "plum3", low="blue", 
                       space="Lab", midpoint = median(myKrige$pred))  + 
  geom_map(data= myKorea, map= myKorea, aes(x=long,y=lat,map_id=id,group=group),
           fill=NA, colour="black") +
  geom_point(data=myPoints, aes(x=LON, y=LAT, fill=PM10), 
             shape=21, alpha=1,na.rm=T, size=3) +
  coord_cartesian(xlim= LON.range, ylim= LAT.range) +
  #scale_size(range=c(2,4))+
  labs(title= "PM10 Concentration in Seoul Area at South Korea",
       x="Longitude", y= "Latitude")+
  theme(title= element_text(hjust = 0.5,vjust = 1,face= c("bold")))

кригинг, наложенный на карту

Изменить: OP запросил точки, сопоставленные с той же цветовой шкалой, вместо fill="yellow", определенных вне эстетики в geom_point(). Визуально это ничего не добавляет, поскольку точки сливаются с кригированным фоном, но код добавляется по запросу.

Edit2: если вы хотите, чтобы график был в исходных координатах широты и долготы, то разные слои необходимо преобразовать в одну и ту же систему координат. Но это преобразование может привести к неправильной сетке, которая не будет работать для geom_tile. Решение 1: stat_summary_2d объединить и усреднить данные по нерегулярной сетке или Решение 2: нанесите большие квадратные точки.

#Reproject the krige data
myKrige1 <- myKrige
coordinates(myKrige1) <- ~LON+LAT 
proj4string(myKrige1) <-"+proj=utm +north +zone=52 +datum=WGS84" 
myKrige_new <- spTransform(myKrige1, CRS("+proj=longlat")) 
myKrige_new <-  data.frame(myKrige_new@coords, pred = myKrige_new@data$pred) 
LON.range.new <- range(myKrige_new$LON) 
LAT.range.new <- range(myKrige_new$LAT)

#Original seoul data have correct lat/lon data
seoul <- read.csv ("seoul032823.csv")   #Reload seoul032823 data

#Original skorea data transformed the same was as myKrige_new
skorea1 <- getData("GADM", country= "KOR", level=1)
#Convert SpatialPolygonsDataFrame to dataframe (deprecated.  see `broom`)
skorea1 <- fortify(skorea1)  
coordinates(skorea1) <- ~long+lat  #{sp} Convert to sp object
proj4string(skorea1) <- "+proj=longlat +datum=WGS84" #{sp} set projection attributes 1
#{sp} Transform to new coordinate reference system
myKorea1 <- spTransform(skorea1, CRS("+proj=longlat")) 
myKorea1 <- data.frame(myKorea1)  #Convert spatial object to data.frame for ggplot

ggplot()+ theme_minimal() +
  #SOLUTION 1:
  stat_summary_2d(data=myKrige_new, aes(x = LON, y = LAT, z = pred),
                  binwidth = c(0.02,0.02)) +
  #SOLUTION 2: Uncomment the line(s) below:
  #geom_point(data = myKrige_new, aes(x= LON, y= LAT, fill = pred),
  #           shape=22, size=8, colour=NA) + 
  scale_fill_gradient2(name=bquote(atop("PM10", mu*g~m^-3)), 
                       high="red", mid= "plum3", low="blue", 
                       space="Lab", midpoint = median(myKrige_new$pred)) + 
  geom_map(data= myKorea1, map= myKorea1, aes(x=long,y=lat,map_id=id,group=group),
           fill=NA, colour="black") +
  geom_point(data= seoul, aes(x=LON, y=LAT, fill=PM10), 
             shape=21, alpha=1,na.rm=T, size=3) +
  coord_cartesian(xlim= LON.range.new, ylim= LAT.range.new) +
  #scale_size(range=c(2,4))+
  labs(title= "PM10 Concentration in Seoul Area at South Korea",
       x="Longitude", y= "Latitude")+
  theme(title= element_text(hjust = 0.5,vjust = 1,face= c("bold")))

карта криг наложена с исходной широтой и долготой

person oshun    schedule 09.04.2016
comment
Ошун, большое спасибо за ответ. некоторые проблемы еще остались. Не могли бы вы последовать примеру карты, приведенной в моем сообщении? 1 ›Мне нужно, чтобы точки на карте имели тот же формат, что и фоновая тепловая карта, для сравнения причин. 2 ›Можно ли обрезать расширенную часть карты, которая отображается рядом с осью y? 3 ›легенды тоже должны быть похожи на картинку в моем посте! 4 ›Как вы упомянули, также необходимо указывать широту и долготу в исходном формате. - person Orpheus; 11.04.2016
comment
1) Задайте заливку внутри aes для точек. Ответ изменен, чтобы показать это. Визуально это не помогает вашему сюжету. 2) Конечно, отредактируйте атрибуты theme. Что-то вроде axis.text.y = element_text(margin = margin(r = 0.3, unit = "cm")) должно работать. 3) Вы можете определить свою цветовую гамму по своему желанию. См. Например scale_colour_gradientn. 4) Я не работаю с пространственными данными, поэтому не знаю. Это должно быть легко, и я буду рад поправить ответ, если вы догадаетесь. - person oshun; 11.04.2016
comment
спасибо ошун. Я преобразовал восточное и северное положение myKrige фрейма данных в широту / долготу. Я назвал этот фрейм данных как myKrige_new следующим кодом: coordinates(myKrige) <- ~LON+LAT proj4string(myKrige) <-"+proj=utm +north +zone=52 +datum=WGS84" myKrige_new <- spTransform(myKrige, CRS("+proj=longlat")) mykrige_new <- data.frame(mykrige_latlon@coords,pred = mykrige_latlon@data$pred) LON.range.new <- range(myKrige_new$LON) LAT.range.new <- range(myKrige_new$LAT) Но когда я пишу код ggplot, geom_tile функция не может работать! можешь проверить, пожалуйста? - person Orpheus; 11.04.2016
comment
1) Но почему форма не прямоугольная? Если я попробую binwidth = c(0.05,0.05) , то получу прямоугольную форму, но размер сетки будет больше! вы можете видеть в моем коде, я сделал прямоугольную сетку для интерполяции кригинга, которая составляла 1500 м * 1500 м. Изменится ли этот размер сетки (разрешение), если я буду использовать полосу пропускания? Теперь я очень смущен! 2) Также я хочу показать лигенд цветовой полосы, которая будет выглядеть равной длине тепловой карты и четко отображать разные цвета для диапазонов значений, как показано на примере графика в моем сообщении. Я пробовал scale_fill_gradientn, но безуспешно! - person Orpheus; 13.04.2016
comment
1) Вам нужно прочитать про stat_summary_2d. 2) Прочитать про scale_fill_. - person oshun; 13.04.2016