求助:分离DataFrame经纬度多边形并使用Cartopy绘图
解决多边形分离与Cartopy绘图问题
我来帮你搞定这个多边形分离和绘图的问题!你的前期数据处理已经做得很到位了,接下来只需要把分组后的多边形数据整理成易操作的结构,再用Cartopy逐个绘制即可,完全适配多边形数量可变、每个多边形的经纬度点数量可变的场景。
第一步:整理分组后的多边形数据
你已经用group_no完成了分组标记,接下来我们可以用groupby把每个多边形的有效经纬度数据存入字典——这样后续遍历绘图会非常方便。
代码实现:
import pandas as pd import numpy as np # 你的前期代码(保留上下文参考) # df = pd.read_excel(xl, sheet_name=0, header=None) # df.rename(columns={1:'lon', 2:'lat'},inplace=True) # df.replace('GAP',np.nan, inplace=True) # df['group_no'] = df.isnull().all(axis=1).cumsum() # 将有效多边形数据存入字典:键是分组编号,值是对应多边形的经纬度DataFrame polygons_dict = { group_id: group_data.dropna(subset=['lon', 'lat']) for group_id, group_data in df.groupby('group_no') if not group_data.dropna(subset=['lon', 'lat']).empty }
代码解释:
- 用字典推导式遍历
groupby的结果,自动跳过那些清理后为空的分组(也就是原来的GAP分隔行所在的分组) - 每个字典值都是仅包含有效经纬度的DataFrame,对应一个完整的多边形
第二步:用Cartopy绘制所有多边形
接下来我们用Cartopy和Matplotlib完成绘图,核心思路是遍历字典中的每个多边形数据,逐个绘制到地图上。
代码实现:
import cartopy.crs as ccrs import matplotlib.pyplot as plt # 创建绘图画布,指定地理投影(这里用常用的PlateCarree,对应经纬度坐标系) fig, ax = plt.subplots(figsize=(10, 8), subplot_kw={'projection': ccrs.PlateCarree()}) # 添加基础地图特征(可选,让地图更清晰) ax.coastlines(resolution='10m') # 海岸线分辨率,可选'10m'/'50m'/'110m' ax.add_feature(ccrs.feature.LAND, facecolor='#f0f0f0') ax.add_feature(ccrs.feature.OCEAN, facecolor='#e0f0ff') # 遍历每个多边形数据,逐个绘制 for poly_idx, (group_id, poly_data) in enumerate(polygons_dict.items(), start=1): # 提取经纬度数组 lons = poly_data['lon'].values lats = poly_data['lat'].values # 绘制闭合多边形:把第一个点的坐标加到数组末尾,保证图形闭合 ax.plot( np.append(lons, lons[0]), # 闭合经度 np.append(lats, lats[0]), # 闭合纬度 label=f'Polygon {poly_idx}', linewidth=2, color=f'C{poly_idx-1}', # 自动循环Matplotlib的默认颜色 transform=ccrs.PlateCarree() # 必须指定数据的投影坐标系 ) # 可选:填充多边形内部(如果需要) # ax.fill( # np.append(lons, lons[0]), # np.append(lats, lats[0]), # alpha=0.2, # 透明度 # color=f'C{poly_idx-1}', # transform=ccrs.PlateCarree() # ) # 添加图例、标题,调整布局 ax.set_title('Multi-Polygon Visualization with Cartopy') plt.legend(loc='upper right') plt.tight_layout() plt.show()
关键细节说明:
- 多边形闭合:必须把第一个点的经纬度加到数组末尾,否则绘制出来的是一条开放的折线,而不是闭合的多边形。
- 投影设置:
transform=ccrs.PlateCarree()是必须的,它告诉Cartopy你的数据是基于经纬度的地理坐标系。 - 灵活性:无论你有多少个多边形、每个多边形有多少个点,这段代码都能自动适配——因为我们是遍历字典中的所有数据,没有硬编码任何数量值。
额外优化建议
- 如果你的经纬度数据是其他坐标系,可以把
ccrs.PlateCarree()替换成对应的投影(比如UTM投影)。 - 可以根据需要调整绘图样式:比如修改线宽、颜色、填充透明度,或者添加点标记来显示每个经纬度点。
- 如果需要保存图片,可以在
plt.show()之前添加plt.savefig('polygons_map.png', dpi=300)。
内容的提问来源于stack exchange,提问作者bd3
相关产品推荐
相关产品推荐

