[英]How to Bound the Outer Area of Voronoi Polygons and Intersect with Map Data
我正在嘗試在美國地圖上使用voronoi polygons
對以下數據進行kmeans
聚類過程的結果可視化。
這是到目前為止我一直在運行的代碼:
input <- read.csv("LatLong.csv", header = T, sep = ",")
# K Means Clustering
set.seed(123)
km <- kmeans(input, 17)
cent <- data.frame(km$centers)
# Visualization
states <- map_data("state")
StateMap <- ggplot() + geom_polygon(data = states, aes(x = long, y = lat, group = group), col = "white")
# Voronoi
V <- deldir(cent$long, cent$lat)
ll <-apply(V$dirsgs, 1, FUN = function(x){
readWKT(sprintf("LINESTRING(%s %s, %s %s)", x[1], x[2], x[3], x[4]))
})
pp <- gPolygonize(ll)=
v_df <- fortify(pp)
# Plot
StateMap +
geom_point(data = input, aes(x = long, y = lat), col = factor(km$cluster)) +
geom_polygon(data = v_df, aes(x = long, y = lat, group = group, fill = id), alpha = .3) +
geom_label(data = cent, aes(x = long, y = lat, label = row.names(cent)), alpha = .3)
我希望能夠綁定多邊形的外部區域並將其與我的美國地圖相交,以便多邊形完全代表美國的陸地區域。 我還沒辦法弄清楚該怎么做。 任何幫助是極大的贊賞。
我提出這個問題的最終目的是編寫一個腳本,在其中我可以任意更改kmeans
簇的數量,並使用覆蓋我想要的區域的voronoi
多邊形快速可視化結果。
我還沒有完全做到這一點,但是我已經取得了足夠的進步,以至於我發現發布的內容可能會導致更快的解決方案。
# Create Input Data.Frame
input <- as.data.frame(cbind(x$long, x$lat))
colnames(input) <- c("long", "lat")
# Set Seed and Run Clustering Procedure
set.seed(123)
km <- kmeans(input, 35)
# Format Output for Plotting
centers <- as.data.frame(cbind(km$centers[,1], km$centers[,2]))
colnames(centers) <- c("long", "lat")
cent.id <- cbind(ID = 1:dim(centers)[1], centers)
# Create Spatial Points Data Frame for Calculating Voronoi Polygons
coords <- centers[,1:2]
vor_pts <- SpatialPointsDataFrame(coords, centers, proj4string = CRS("+proj=longlat +datum=WGS84"))
我還發現了以下內容。 功能 ,同時尋找解決的辦法上網。
# Function to Extract Voronoi Polygons
SPdf_to_vpoly <- function(sp) {
# tile.list extracts the polygon data from the deldir computation
vor_desc <- tile.list(deldir(sp@coords[,1], sp@coords[,2]))
lapply(1:length(vor_desc), function(i) {
# tile.list gets us the points for the polygons but we
# still have to close them, hence the need for the rbind
tmp <- cbind(vor_desc[[i]]$x, vor_desc[[i]]$y)
tmp <- rbind(tmp, tmp[1,])
# Now we can make the polygons
Polygons(list(Polygon(tmp)), ID = i)
}) -> vor_polygons
# Hopefully the caller passed in good metadata
sp_dat <- sp@data
# This way the IDs should match up with the data & voronoi polys
rownames(sp_dat) <- sapply(slot(SpatialPolygons(vor_polygons), 'polygons'), slot, 'ID')
SpatialPolygonsDataFrame(SpatialPolygons(vor_polygons), data = sp_dat)
}
通過上述功能,可以相應地提取多邊形
vor <- SPdf_to_vpoly(vor_pts)
vor_df <- fortify(vor)
為了使voronoi
多邊形與美國地圖很好地匹配,我從Census
網站下載了cb_2014_us_state_20m並運行了以下命令:
# US Map Plot to Intersect with Voronoi Polygons - download from census link and place in working directory
us.shp <- readOGR(dsn = ".", layer = "cb_2014_us_state_20m")
state.abb <- state.abb[!state.abb %in% c("HI", "AK")]
Low48 <- us.shp[us.shp@data$STUSPS %in% state.abb,]
# Define Area Polygons and Projections and Calculate Intersection
Low48.poly <- as(Low48, "SpatialPolygons")
vor.poly <- as(vor, "SpatialPolygons")
proj4string(vor.poly) <- proj4string(Low48.poly)
intersect <- gIntersection(vor.poly, Low48.poly, byid = T)
# Convert to Data Frames to Plot with ggplot
Low48_df <- fortify(Low48.poly)
int_df <- fortify(intersect)
從這里,我可以像以前一樣使用ggplot
可視化我的結果:
# Plot Results
StateMap <- ggplot() + geom_polygon(data = Low48_df, aes(x = long, y = lat, group = group), col = "white")
StateMap +
geom_polygon(data = int_df, aes(x = long, y = lat, group = group, fill = id), alpha = .4) +
geom_point(data = input, aes(x = long, y = lat), col = factor(km$cluster)) +
geom_label(data = centers, aes(x = long, y = lat, label = row.names(centers)), alpha =.2) +
scale_fill_hue(guide = 'none') +
coord_map("albers", lat0 = 30, lat1 = 40)
重疊的voronoi
多邊形仍然不是一個完美的擬合(我想是由於西北太平洋地區缺乏輸入數據),盡管我認為這應該是一個簡單的解決方法,我會盡快對其進行更新。可能。 另外,如果我在函數開始時更改了kmeans centroids
的數量,然后重新運行所有多邊形,這些多邊形看起來根本不是很好,這並不是我最初希望的。 我將繼續改進。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.