Matplotlib中散点图标记与mlines图例标记尺寸不一致问题求解
解决散点图标记尺寸与图例不一致的问题
你遇到的问题核心是:ax.scatter()里的s参数控制的是标记的面积,而图例中mlines.Line2D的markersize控制的是标记的直径(像素值),两者计算逻辑完全不同,直接手动设置markersize会出现尺寸不匹配的情况。
解决思路
要让图例标记和散点标记尺寸一致,需要把散点的面积值s转换成对应的直径值,换算公式为:
markersize = np.sqrt(s / np.pi)
基于这个公式,我们可以直接用你定义的sizes数组计算图例所需的markersize,无需手动逐个设置。
修改后的完整代码
下面是调整完图例部分的代码,重点优化了图例标记尺寸的计算,同时简化了重复代码:
import numpy as np import matplotlib.pyplot as plt import matplotlib.lines as mlines import cartopy.crs as ccrs import cartopy.feature as cfeature from cartopy.feature import NaturalEarthFeature # 原数据处理逻辑不变 conditions = [(maxcwd1['CWD'] == 0), (maxcwd1['CWD'] > 0) & (maxcwd1['CWD'] < 3), (maxcwd1['CWD'] >= 3) & (maxcwd1['CWD'] < 5), (maxcwd1['CWD'] >= 5) & (maxcwd1['CWD'] < 7), (maxcwd1['CWD'] >= 7) & (maxcwd1['CWD'] < 10), (maxcwd1['CWD'] >= 10) & (maxcwd1['CWD'] < 15), (maxcwd1['CWD'] >= 15) & (maxcwd1['CWD'] < 20), (maxcwd1['CWD'] >= 20) & (maxcwd1['CWD'] <= 31) ] sizes = [100,200,300,400,500,600,700,800] maxcwd1['size'] = np.select(conditions, sizes) # 原绘图逻辑不变 fig = plt.figure('map', figsize=(20,25), dpi=300) ax = fig.add_axes([0.05, 0.05, 0.90, 0.85], projection=ccrs.PlateCarree()) l1 = NaturalEarthFeature(category='cultural', name='admin_0_countries', scale='50m', facecolor='none') ax.add_feature(cfeature.OCEAN.with_scale('50m'), facecolor='deepskyblue') ax.add_feature(cfeature.LAND.with_scale('50m')) ax.add_feature(cfeature.COASTLINE.with_scale('50m')) ax.add_feature(COUNTIES, edgecolor='black',linewidth=0.5,facecolor='#BDBBC4',zorder=2) ax.add_feature(COUNTIES_P, edgecolor='black',linewidth=0.5,facecolor='#E1E1E1',zorder=2) for index, row in maxcwd1.iterrows(): ax.scatter(row['Longitud'], row['Latitud'], s=row['size'], color='black', marker='o',edgecolors="black",linewidth=1,zorder=4,transform=ccrs.PlateCarree()) # 优化后的图例创建逻辑 labels = ['0', '[1-3>', '[3-5>', '[5-7>', '[7-10>', '[10-15>', '[15-20>', '[20-31]'] handles = [] for s, label in zip(sizes, labels): # 根据面积计算对应markersize ms = np.sqrt(s / np.pi) handle = mlines.Line2D([], [], color='black', marker='o', linestyle='None', markeredgecolor='black', markersize=ms, label=label) handles.append(handle) leg=ax.legend(handles=handles,title='CWD',title_fontsize=20, fontsize=22, bbox_to_anchor=(0.04, 0.22, 0.1, 0.35), borderpad=0.45, labelspacing=0.75,handlelength=0.4, facecolor='white',edgecolor='black',borderaxespad=0.004) plt.show()
额外说明
- 用循环批量创建图例手柄,既避免重复代码,也能保证每个标记的尺寸计算准确
- 后续如果调整
sizes数组,图例标记尺寸会自动同步更新,无需手动修改
内容的提问来源于stack exchange,提问作者Javier
相关产品推荐
相关产品推荐

