我感兴趣的是绘制艾姆斯数据集中邻域的多边形/凸船体表示,类似于O 'Reilly版本的Tidy-modeling with R中使用的方法。
看起来,同一段落的第4章有两个不同的图像,这取决于您使用的来源,第一个图像来自here的O 'Reilly版本,第二个来自tmwr.org
x1c 0d1x的数据
就个人而言,我更喜欢第一个,因为它更容易看到相邻区域的重叠。Tmwr.org有一个GitHub repo,但是凸船体代码没有在那里捕获。
从他们的仓库中,我可以看到他们从this网站下载了一个形状文件,并将其用于背景中的道路Map,然后覆盖多边形。
我试图创建多边形,并使用谷歌Map作为背景,但我没有太大的成功添加谷歌Map层。
在代码的底部,我可以绘制谷歌Map层,但当我引入ames_sf
时,我得到以下错误:
Error in `geom_sf()`:
! Problem while computing aesthetics.
ℹ Error occurred in the 4th layer.
Caused by error:
! object 'lon' not found
字符串
从我用ggplot生成的凸包和谷歌Map图像可以看出,他们使用了不同的坐标值,这可能是问题所在。我很困惑,因为在第46行ames_sf
是用crs = 3857
定义的,然后在第90行的底部ggmap(map)
被传递给coord_sf
,其中st_crs
也被设置为3857。
下面是我拼凑的代码(其中一些来自here),目前我正在寻找一些帮助,在googleMap的背景分层。任何可以分享的帮助将不胜感激。
# LOAD THE REQUIRED LIBRARIES
pacman::p_load(sf, ggplot2, dplyr, RColorBrewer, AmesHousing)
# ASSIGN A PALETTE OF 8 COLORS FROM THE 'DARK2' PALETTE TO A VARIABLE
col_vals <- brewer.pal(8, "Dark2")
# CREATE A NAMED VECTOR 'ames_cols' WITH NEIGHBORHOOD NAMES MAPPED TO SPECIFIC COLORS FROM 'col_vals'
# COPIED FROM THE TMWR.ORG REPO
ames_cols <- c(
North_Ames = col_vals[3],
College_Creek = col_vals[4],
Old_Town = col_vals[8],
Edwards = col_vals[5],
Somerset = col_vals[8],
Northridge_Heights = col_vals[4],
Gilbert = col_vals[2],
Sawyer = col_vals[7],
Northwest_Ames = col_vals[6],
Sawyer_West = col_vals[8],
Mitchell = col_vals[3],
Brookside = col_vals[1],
Crawford = col_vals[4],
Iowa_DOT_and_Rail_Road = col_vals[2],
Timberland = col_vals[2],
Northridge = col_vals[1],
Stone_Brook = col_vals[5],
South_and_West_of_Iowa_State_University = col_vals[3],
Clear_Creek = col_vals[1],
Meadow_Village = col_vals[1],
Briardale = col_vals[7],
Bloomington_Heights = col_vals[1],
Veenker = col_vals[2],
Northpark_Villa = col_vals[2],
Blueste = col_vals[5],
Greens = col_vals[6],
Green_Hills = col_vals[8],
Landmark = col_vals[3],
Hayden_Lake = "red" # 'Hayden_Lake' SPECIFICALLY ASSIGNED THE COLOR RED
)
# LOAD AND PREPARE THE AMES HOUSING DATA
ames_data <- make_ames() %>%
janitor::clean_names()
# CONVERT AMES DATA INTO AN SF (SIMPLE FEATURES) OBJECT FOR SPATIAL ANALYSIS AND
# TRANSFORM EPSG 3857 (Pseudo-Mercator, what Google uses)
ames_sf <- st_as_sf(ames_data, coords = c("longitude", "latitude"), crs = 3857)
# CREATE POLYGONS FOR EACH NEIGHBORHOOD BY AGGREGATING POINTS INTO A CONVEX HULL
ames_sf <- ames_sf %>%
group_by(neighborhood) %>%
summarize() %>%
st_convex_hull()
# PLOT THE CONVEX HULLS USING GGPLOT
#ggplot(data = ames_sf) +
# geom_sf(aes(fill = neighborhood), color = "white", size = 0.5) +
# scale_fill_manual(values = ames_cols) +
# theme_minimal() +
# labs(title = 'Neighborhoods in Ames') +
# theme(legend.position = "none")
map <- get_map("Ames, Iowa", maptype = "roadmap", zoom = "auto", scale = "auto", source = "google")
# Define a function to fix the bbox to be in EPSG:3857
ggmap_bbox <- function(map) {
if (!inherits(map, "ggmap")) stop("map must be a ggmap object")
# Extract the bounding box (in lat/lon) from the ggmap to a numeric vector,
# and set the names to what sf::st_bbox expects:
map_bbox <- setNames(
unlist(attr(map, "bb")),
c("ymin", "xmin", "ymax", "xmax")
)
# Coonvert the bbox to an sf polygon, transform it to 3857,
# and convert back to a bbox (convoluted, but it works)
bbox_3857 <- st_bbox(st_transform(st_as_sfc(st_bbox(map_bbox, crs = 4326)), 3857))
# Overwrite the bbox of the ggmap object with the transformed coordinates
attr(map, "bb")$ll.lat <- bbox_3857["ymin"]
attr(map, "bb")$ll.lon <- bbox_3857["xmin"]
attr(map, "bb")$ur.lat <- bbox_3857["ymax"]
attr(map, "bb")$ur.lon <- bbox_3857["xmax"]
map
}
# Use the function:
map <- ggmap_bbox(map)
ggmap(map) +
coord_sf(crs = st_crs(3857)) + # force the ggplot2 map to be in 3857
geom_sf(data = ames_sf, aes(fill = neighborhood), color = "white", size = 0.5, alpha = 0.5)
型
使用ggmaps我可以创建多边形并将它们打印到坐标网格中,但我很难添加到Map背景中。
1条答案
按热度按时间uoifb46i1#
当你在你的问题中比较这两个图时,你应该注意的第一件事(或至少第二件事)是纬度/经度值的差异。即使不太确定纬度/经度的正常范围应该是什么,将美国的住房数据放在赤道上(纬度~0)是一个非常清楚的指标,最好后退几步。
这里的罪魁祸首是crs处理,使用
st_as_sf(ames_data, ... ,crs = 3857)
,您实际上并没有转换坐标,而是将经度/纬度值定义为3857伪墨卡托的东距和北距,这里的crs
应该与输入坐标的实际crs匹配。要尽早发现此类问题,请在每一步之后尽可能多地可视化地理空间数据,如果需要的话。使用像mapview()
这样的东西要方便得多以下示例使用OpenStreetMap数据的
ggspatial
和Carto Light渲染,而不是ggmap
和Google tiles。字符串
x1c 0d1x的数据
型
创建于2023-11-06附带reprex v2.0.2