You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

额外注意事项

  1. 确保COUNTYFIPS是字符类型:如果是数值型,开头带0的县FIPS码会丢失前导零,导致匹配失败
  2. 检查RISK_SCORE是数值型:plotly的z参数必须传入数值数据,否则无法生成颜色映射
  3. 叠加自有数据时,用dplyr::left_join()关联即可,确保两边的关联字段(如COUNTYFIPS)完全匹配

内容的提问来源于stack exchange,提问作者Ashti

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 05:20:10