使用Plotly结合Shapefile绘制Choropleth地图失败原因咨询
问题分析与解决方案
核心问题1:sf_geojson()的返回值类型错误
你调用sf_geojson(counties)后得到的是JSON格式的字符串,而非带属性的数据框/列表结构。所以counties_geo$COUNTYFIPS、counties_geo$RISK_SCORE这类写法完全无效——字符串不存在$索引的属性。
核心问题2:plotly choropleth参数适配错误
普通choropleth类型更适配plotly内置的地理边界(如美国州级数据),自定义Shapefile数据更适合用choroplethmapbox类型,同时需要搭配地图布局设置,否则地图无法正常渲染。
修正后的代码(推荐方案:直接用sf对象)
这个方案更简洁,且能直接保留sf对象的属性,方便后续叠加自有数据:
library(sf);library(dplyr);library(plotly) # 读取Shapefile,保留sf对象结构 counties <- st_read(dsn="~/Climate Change/NRI_Shapefile_Counties/NRI_Shapefile_Counties.shp") # 若要叠加自有数据,直接用left_join关联(假设自有数据有COUNTYFIPS字段) # counties <- counties %>% left_join(your_own_data, by = "COUNTYFIPS") fig <- plot_ly() fig <- fig %>% add_trace( data = counties, type = "choroplethmapbox", # 适配自定义地理数据的类型 geojson = st_geojson(counties), locations = ~COUNTYFIPS, # 直接引用sf对象的字段 z = ~RISK_SCORE, showscale = TRUE, text = ~paste(COUNTY, "<br>Risk Rating:", RISK_RATNG), hoverinfo = "text", marker = list(line = list(width = 0)) ) %>% layout(mapbox = list(style = "carto-positron", zoom = 3)) # 必须添加地图布局 fig
备选方案:坚持用choropleth类型
如果一定要使用普通choropleth,需要将JSON字符串转成R列表,再手动提取属性:
library(sf);library(dplyr);library(plotly);library(jsonlite) counties <- st_read(dsn="~/Climate Change/NRI_Shapefile_Counties/NRI_Shapefile_Counties.shp") # 将JSON字符串转成可索引的列表 counties_geo <- fromJSON(sf_geojson(counties), simplifyVector = FALSE) # 手动提取每个地理特征的属性 fips_list <- sapply(counties_geo$features, function(x) x$properties$COUNTYFIPS) risk_score_list <- sapply(counties_geo$features, function(x) x$properties$RISK_SCORE) hover_text_list <- sapply(counties_geo$features, function(x) paste(x$properties$COUNTY, "<br>Risk Rating:", x$properties$RISK_RATNG)) fig <- plot_ly() fig <- fig %>% add_trace( type = "choropleth", geojson = counties_geo, locations = fips_list, z = risk_score_list, showscale = TRUE, text = hover_text_list, hoverinfo = "text", marker = list(line = list(width = 0)) ) %>% layout(geo = list(scope = "usa")) # 限定地理范围为美国,确保边界正确显示 fig
额外注意事项
- 确保
COUNTYFIPS是字符类型:如果是数值型,开头带0的县FIPS码会丢失前导零,导致匹配失败 - 检查
RISK_SCORE是数值型:plotly的z参数必须传入数值数据,否则无法生成颜色映射 - 叠加自有数据时,用
dplyr::left_join()关联即可,确保两边的关联字段(如COUNTYFIPS)完全匹配
内容的提问来源于stack exchange,提问作者Ashti
相关产品推荐
相关产品推荐

