Plotly绘制县级FIPS数据Choropleth地图遇MultiPolygon不可迭代错误
解决Plotly绘制县级Choropleth地图的TypeError问题
问题重现
运行官方示例代码绘制佛罗里达州县级人口 choropleth 地图时,抛出错误:
TypeError: 'MultiPolygon' object is not iterable
原代码如下:
import plotly.figure_factory as ff import numpy as np import pandas as pd df_sample = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/minoritymajority.csv') df_sample_r = df_sample[df_sample['STNAME'] == 'Florida'] values = df_sample_r['TOT_POP'].tolist() fips = df_sample_r['FIPS'].tolist() endpts = list(np.mgrid[min(values):max(values):4j]) colorscale = ["#030512","#1d1d3b","#323268","#3d4b94","#3e6ab0", "#4989bc","#60a7c7","#85c5d3","#b7e0e4","#eafcfd"] fig = ff.create_choropleth( fips=fips, values=values, scope=['Florida'], show_state_data=True, colorscale=colorscale, binning_endpoints=endpts, round_legend_values=True, plot_bgcolor='rgb(229,229,229)', paper_bgcolor='rgb(229,229,229)', legend_title='Population by County', county_outline={'color': 'rgb(255,255,255)', 'width': 0.5}, exponent_format=True, ) fig.layout.template = None fig.show()
问题原因
这个错误源于Shapely 2.x+版本的API变更:旧版Shapely允许直接迭代MultiPolygon对象,新版则需要通过geoms属性访问其包含的多边形。而plotly.figure_factory.create_choropleth的底层逻辑还未适配该变更,导致迭代MultiPolygon时出错。
解决方案
方案1:临时补丁适配Shapely 2.x
在代码开头添加一段补丁,让MultiPolygon对象支持旧版迭代方式,无需修改原绘图逻辑:
# 先添加补丁代码 import shapely.geometry.multipolygon def _multipolygon_iter(self): yield from self.geoms shapely.geometry.multipolygon.MultiPolygon.__iter__ = _multipolygon_iter # 然后是原有的绘图代码 import plotly.figure_factory as ff import numpy as np import pandas as pd df_sample = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/minoritymajority.csv') df_sample_r = df_sample[df_sample['STNAME'] == 'Florida'] values = df_sample_r['TOT_POP'].tolist() fips = df_sample_r['FIPS'].tolist() endpts = list(np.mgrid[min(values):max(values):4j]) colorscale = ["#030512","#1d1d3b","#323268","#3d4b94","#3e6ab0", "#4989bc","#60a7c7","#85c5d3","#b7e0e4","#eafcfd"] fig = ff.create_choropleth( fips=fips, values=values, scope=['Florida'], show_state_data=True, colorscale=colorscale, binning_endpoints=endpts, round_legend_values=True, plot_bgcolor='rgb(229,229,229)', paper_bgcolor='rgb(229,229,229)', legend_title='Population by County', county_outline={'color': 'rgb(255,255,255)', 'width': 0.5}, exponent_format=True, ) fig.layout.template = None fig.show()
方案2:改用Plotly Express(推荐)
Plotly官方现在更推荐使用plotly.express的choropleth_mapbox绘制地理地图,它对新版Shapely兼容性更好,代码也更简洁:
import plotly.express as px import pandas as pd df_sample = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/minoritymajority.csv') df_sample_r = df_sample[df_sample['STNAME'] == 'Florida'] fig = px.choropleth_mapbox( df_sample_r, geojson="https://raw.githubusercontent.com/plotly/datasets/master/geojson-counties-fips.json", locations='FIPS', color='TOT_POP', color_continuous_scale=["#030512","#1d1d3b","#323268","#3d4b94","#3e6ab0", "#4989bc","#60a7c7","#85c5d3","#b7e0e4","#eafcfd"], range_color=(df_sample_r['TOT_POP'].min(), df_sample_r['TOT_POP'].max()), mapbox_style="carto-positron", zoom=6, center={"lat": 27.9944, "lon": -81.7603}, # 佛罗里达州中心坐标 labels={'TOT_POP':'Population'}, title='Population by County (Florida)' ) fig.update_layout(margin={"r":0,"t":40,"l":0,"b":0}) fig.show()
该方案无需依赖旧版Shapely,同时支持交互性更强的Mapbox地图,更适合长期使用。
内容的提问来源于stack exchange,提问作者Tyler
相关产品推荐
相关产品推荐

