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

Geopandas绘制路网时遇'MultiLineString不可迭代'错误求助

公交路线优化遗传算法项目绘图报错:TypeError: 'MultiLineString' object is not iterable

复现GitHub上的公交路线优化遗传算法项目时,已修复多数错误,但在绘制路线网络时触发TypeError: 'MultiLineString' object is not iterable错误,该错误指向代码中的self.roads.plot(ax=ax,color='black', linewidth=.5 )语句。打印self.roads.geometry显示其类型为LINESTRING,但仍出现上述错误。当前使用版本为geopandas=0.6.0、threadpoolctl=3.2.0,尝试过搜索该错误及相关方案,但均未解决问题。

相关代码

def plot(self):
    '''
    OUTPUT: plot of routes
    '''

    fig = plt.figure(figsize=(18,12))
    for n in range(self.N):
        # Make LineString Objects
        route_a_line = self.route_line(self.route_list[n][1])
        route_b_line = self.route_line(self.route_list[n][2])

        # Make Geo DataFrames
        route_a_geo = self.transform_to_GeoDataFrame(route_a_line)
        route_b_geo = self.transform_to_GeoDataFrame(route_b_line)

        ax = fig.add_subplot(2,2,n+1)
        ax.set_aspect('equal')
        
        print(self.roads.geometry)
        
        self.roads.plot(ax=ax,color='black', linewidth=.5 )
        self.region.plot(ax=ax, color='orange', alpha=.2)
        self.bus_stops_geo.plot(ax=ax, color='red',markersize=8)

        route_a_geo.plot(ax=ax, color='green', linewidth=1)
        route_b_geo.plot(ax=ax, color='blue', linewidth=1)

        ax.set_title('East Side Route Map {}\nFitness = {}'.format(n+1,self.route_list[n][0]))
        ax.set_ylim((self.miny, self.maxy))
        ax.set_xlim((self.minx, self.maxx))
        ax.set_xticks([])
        ax.set_yticks([])

    plt.subplots_adjust(left=None, bottom=None, right=None, top=None, wspace=.1, hspace=.1)
    plt.show()

输出及报错信息

40       LINESTRING (-97.68178 30.28154, -97.68239 30.2...
103      LINESTRING (-97.68271 30.28083, -97.68212 30.2...
145      LINESTRING (-97.69771 30.25189, -97.69632 30.2...
146      LINESTRING (-97.72316 30.28912, -97.72312 30.2...
157      LINESTRING (-97.73329 30.27056, -97.73312 30.2...
...
19248    LINESTRING (-97.71925 30.27073, -97.71828 30.2...
19374    LINESTRING (-97.73050 30.27595, -97.73046 30.2...
19393    LINESTRING (-97.73050 30.27595, -97.73046 30.2...
19416    LINESTRING (-97.71351 30.25043, -97.71343 30.2...
19553    LINESTRING (-97.73230 30.24584, -97.73143 30.2...
Name: geometry, Length: 662, dtype: geometry

TypeError                                 Traceback (most recent call last)
Cell In[16], line 1
----> 1 model.plot()

File ~\Downloads\Bus-Route-Optimization-master\RouteFinder1.0\RouteFinder.py:296, in RouteFinder.plot(self)
    288 print(self.roads.geometry)
    290 #if (self.roads.geometry.type == 'MultiLineString').any():
    291 #    for line in self.roads.geometry:
    292 #        ax.plot(*line.xy, color='black', linewidth=.5)
    293 #else:
    294 #    ax.plot(*self.roads.geometry.xy, color='black', linewidth=.5)
--> 296 self.roads.plot(ax=ax,color='black', linewidth=.5 )
    297 self.region.plot(ax=ax, color='orange', alpha=.2)
    298 self.bus_stops_geo.plot(ax=ax, color='red',markersize=8)

File C:\ProgramData\Anaconda3\lib\site-packages\geopandas\geodataframe.py:606, in GeoDataFrame.plot(self, *args, **kwargs)
    596 def plot(self, *args, **kwargs):
    597     """Generate a plot of the geometries in the GeoDataFrame.
    598 
    599     If the column parameter is given, colors plot according to values
    (...)
    604     from there.
    605     """
--> 606     return plot_dataframe(self, *args, **kwargs)

File C:\ProgramData\Anaconda3\lib\site-packages\geopandas\plotting.py:495, in plot_dataframe(df, column, cmap, color, ax, cax, categorical, legend, scheme, k, vmin, vmax, markersize, figsize, legend_kwds, classification_kwds, **style_kwds)
    492     markersize = df[markersize].values
    494 if column is None:
--> 495     return plot_series(
    496         df.geometry,
    497         cmap=cmap,
    498         color=color,
    499         ax=ax,
    500         figsize=figsize,
    501         markersize=markersize,
    502         **style_kwds
    503     )
    505 # To accept pd.Series and np.arrays as column
    506 if isinstance(column, (np.ndarray, pd.Series)):

File C:\ProgramData\Anaconda3\lib\site-packages\geopandas\plotting.py:348, in plot_series(s, cmap, color, ax, figsize, **style_kwds)
    346 if not lines.empty:
    347     values_ = values[line_idx] if cmap else None
--> 348     plot_linestring_collection(
    349         ax, lines, values_, color=color, cmap=cmap, **style_kwds
    350     )
    352 # plot all Points in the same collection
    353 points = s.geometry[point_idx]

File C:\ProgramData\Anaconda3\lib\site-packages\geopandas\plotting.py:156, in plot_linestring_collection(ax, geoms, values, color, cmap, vmin, vmax, **kwargs)
    129 """
    130 Plots a collection of LineString and MultiLineString geometries to ax
    131 
    (...)
    152 
    153 """
    154 from matplotlib.collections import LineCollection
--> 156 geoms, multiindex = _flatten_multi_geoms(geoms, range(len(geoms)))
    157 if values is not None:
    158     values = np.take(values, multiindex)

File C:\ProgramData\Anaconda3\lib\site-packages\geopandas\plotting.py:38, in _flatten_multi_geoms(geoms, colors)
     36 for geom, color in zip(geoms, colors):
     37     if geom.type.startswith("Multi"):
---> 38         for poly in geom:
     39             components.append(poly)
     40             # repeat same color for all components

TypeError: 'MultiLineString' object is not iterable

解决思路与方案

  1. 根源定位:打印的self.roads.geometry仅显示部分条目,实际数据中存在隐藏的MultiLineString对象。旧版geopandas(0.6.0)处理MultiLineString时的迭代逻辑存在bug,直接遍历MultiLineString对象会触发不可迭代错误。

  2. 方案一:手动绘制几何对象(推荐)
    替换原有的self.roads.plot()调用,手动处理所有几何类型,绕过geopandas的bug:

    # 替换原self.roads.plot(...)语句
    for geom in self.roads.geometry:
        if geom.type == 'LineString':
            ax.plot(*geom.xy, color='black', linewidth=.5)
        elif geom.type == 'MultiLineString':
            # 正确遍历MultiLineString的子线段
            for line in geom.geoms:
                ax.plot(*line.xy, color='black', linewidth=.5)
    
  3. 方案二:升级geopandas版本
    旧版geopandas(0.6.0)存在诸多已知bug,升级到1.0+版本可彻底解决这类几何对象迭代问题:

    pip install --upgrade geopandas
    

    注意:升级需同步检查依赖库(如shapely、pandas)的兼容性,确保项目其他代码正常运行。

  4. 方案三:预处理数据拆分MultiLineString
    在加载self.roads数据时,提前将所有MultiLineString拆分为LineString:

    import geopandas as gpd
    
    # 拆分MultiLineString为单个LineString
    def explode_multilinestring(gdf):
        exploded = []
        for idx, row in gdf.iterrows():
            if row.geometry.type == 'MultiLineString':
                for line in row.geometry.geoms:
                    new_row = row.drop('geometry').to_dict()
                    new_row['geometry'] = line
                    exploded.append(new_row)
            else:
                exploded.append(row.to_dict())
        return gpd.GeoDataFrame(exploded, crs=gdf.crs)
    
    # 在初始化self.roads后调用
    self.roads = explode_multilinestring(self.roads)
    

    预处理后self.roads仅包含LineString,可直接使用原plot()方法。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 17:12:03