从坐标点创建等值线图

时间:2017-08-26 01:05:03

标签: r ggplot2 gis choropleth

我有一个数据框,包含多个具有特定地理坐标(纬度和经度)的数据点。我正在寻找创建一个等值的世界地图,根据该地区边界内有多少数据点,地理区域被遮蔽。

有没有一种简单的方法来完成我在R中尝试做的事情,最好使用“maps”包的世界地图和“ggplot2”地图绘制功能?

以下是我所拥有的最低限度的可重复结果:

library(ggplot2)
library(maps)

data <- data.frame(lat = 40.730610, lon = -73.935242)

ggplot() + 
  geom_polygon(data = map_data("world"), aes(x = long, y = lat, group = group, fill = group)) +
  coord_fixed(1.3)

我注意到绘图项功能的fill参数可用于创建等值线效果。在这里,fill函数的aes()函数上的geom_polygon()参数用于创建一个等值区,其中每个组的颜色编码方式不同。

1 个答案:

答案 0 :(得分:4)

有很多方法可以完成这项任务。一般的想法是将点数据和多边形数据都转换为空间对象。之后,计算该多边形内有多少个点。我知道我们可以使用sp包来做这件事,这个广泛且在R社区中很有名,但我决定使用sf包,因为sf将成为下一代R(https://cran.r-project.org/web/packages/sf/index.html)中的空间对象标准。了解sf的用法和功能可能会有所帮助。

首先,OP提供了一个示例点,但我决定添加更多点,以便我们可以看到如何计算点数并聚合数据。为此,我使用ggmap pakcage对我选择的一些城市进行地理编码作为示例。

# Load package
library(tidyverse)
library(ggmap)
library(maps)
library(maptools)
library(sf)

# Create point data as a data frame
point_data <- data.frame(lat = 40.730610, lon = -73.935242)

# Geocode a series of cities
city <- c("Detroit", "Seattle", "Toranto", "Denver", "Mexico City", "Paris", "New Orleans",
          "Tokyo", "Osaka", "Beijing", "Canberra", "New York", "Istanbul", "New Delhi",
          "London", "Taipei", "Seoul", "Manila", "Bangkok", "Lagos", "Chicago", "Shanghai")
point_data2 <- geocode(city)

# Combine OP's example and the geocoding result
point_data3 <- bind_rows(point_data, point_data2)

接下来,我将point_data3数据框转换为sf对象。我还将使用maps包获取世界的多边形数据,并将其转换为sf对象。

# Convert to simple feature object
point_sf <- st_as_sf(point_data3, coords = c("lon", "lat"), crs = 4326)

# Get world map data
worldmap <- maps::map("world", fill = TRUE, plot = FALSE)

# Convert world to sp class
IDs <- sapply(strsplit(worldmap$names, ":"), "[", 1L)
world_sp <- map2SpatialPolygons(worldmap, IDs = IDs, 
                                proj4string = CRS("+proj=longlat +datum=WGS84"))

# Convert world_sp to simple feature object
world_sf <- st_as_sf(world_sp)

# Add country ID
world_sf <- world_sf %>%
  mutate(region = map_chr(1:length(world_sp@polygons), function(i){
    world_sp@polygons[[i]]@ID
  }))

现在,point_sfworld_sf都是sf个对象。我们可以使用st_within函数来检查哪些点位于哪个多边形内。

# Use st_within
result <- st_within(point_sf, world_sf, sparse = FALSE)

# Calculate the total count of each polygon
# Store the result as a new column "Count" in world_sf
world_sf <- world_sf %>%
  mutate(Count = apply(result, 2, sum))

总计数信息位于Count的{​​{1}}列中。我们可以像OP一样使用world_sf函数获取世界数据框。然后,我们可以合并map_dataworld_data

world_df

现在我们准备绘制数据了。以下代码与OP的ggplot代码相同,只是输入数据现在是# Convert world_sf to a data frame world_df world_df <- world_sf st_geometry(world_df) <- NULL # Get world data frame world_data <- map_data("world") # Merge world_data and world_df world_data2 <- world_data %>% left_join(world_df, by = c("region")) world_data2

fill = Count