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

Matplotlib true_scatter函数问题:散点圆实际半径与预期不符

问题排查与修正:Matplotlib真实半径散点图

问题根源

你的true_scatter函数计算像素-数据单位比例时,错误使用了整个figure的宽度,而非绘图轴(ax)的实际显示宽度。figure包含边距、刻度标签等元素,轴的实际宽度远小于figure宽度,导致计算出的缩放比例偏大,最终生成的圆形面积(对应scatter的s参数)比预期大,视觉上半径约为1.55而非1。

另外,示例代码中调用函数后重复设置xlim和ylim的操作冗余,虽当前设置范围一致,但可能在其他场景下破坏等比例轴的布局。

修正后的代码

import matplotlib.pyplot as plt
import numpy as np

def true_scatter(x, y, r, ax, **kwargs):
    # 确保轴为等比例
    ax.set_aspect('equal')
    
    # 获取轴的实际显示参数
    dpi = ax.figure.dpi
    # 获取轴的实际宽度(像素)和数据范围
    ax_width_pixels = ax.get_window_extent().width
    xlim = ax.get_xlim()
    plot_width_data_units = xlim[1] - xlim[0]

    # 计算像素/数据单位的缩放比例
    scale = ax_width_pixels / plot_width_data_units

    # 将数据单位半径转换为平方点(scatter的s参数单位)
    radius_pixels = r * scale
    area_pixels = np.pi * (radius_pixels ** 2)
    # 1英寸=72点,1英寸=dpi像素 → 1像素=72/dpi点,面积转换为平方点
    area_points = area_pixels * (72 / dpi) ** 2

    # 绘制散点
    scatter = ax.scatter(x, y, s=area_points, **kwargs)
    return scatter

# 测试示例
fig, ax = plt.subplots()
# 先设置轴范围,再调用函数
ax.set_xlim(-2, 2)
ax.set_ylim(-2, 2)
scatter = true_scatter(0, 0, 1, ax, facecolor='none', edgecolor='red')
# 添加参考线验证半径
ax.axvline(x=1, color='gray', linestyle='--')
ax.axhline(y=1, color='gray', linestyle='--')
plt.grid()
plt.show()

关键修改点

  • 使用轴的实际宽度:通过ax.get_window_extent().width获取轴的真实显示宽度(像素),替代原代码中整个figure的宽度,确保缩放比例计算准确。
  • 移除冗余的轴范围设置:只在调用函数前设置一次xlim和ylim,避免破坏等比例轴的布局。
  • 添加参考线:测试代码中加入了x=1和y=1的虚线,可直观验证圆形半径是否符合预期。

验证方法

运行修正后的代码,红色空心圆的边缘会刚好对齐灰色参考线,说明半径准确为1个数据单位。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 10:52:18