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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 21:57:48