Python Matplotlib Quiverplot绘制异常:部分点位未显示矢量数据排查
Matplotlib Quiver 图部分点位无矢量的问题排查与修复
核心根因
部分点位未渲染矢量,本质是计算得到的矢量数组中存在NaN、inf等非法值。quiver函数遇到对应点位的非法值时会直接跳过绘制,且不会抛出显式报错,容易让使用者误以为代码语法完全正确。
触发非法值的具体原因:
- 网格序列覆盖了除零触发点:代码中
Y = np.arange(-2,2,.1)生成的坐标列表会精确包含y=0.0的点位,对应v分量计算中-(m1/(abs(y))**3)*(y)-(m2/(abs(y))**3)*(y)项会触发0/0浮点运算,直接输出NaN。由于这一行y=0覆盖所有x坐标,会直接形成横跨整个绘图区的空白横带。 - 引力源位置的除零隐患:
u分量计算中,引力源位置为x1=4/3、x2=2/3,当网格点坐标与这两个值重合时,同样会触发(x-x1)/abs(x-x1)**3形式的0/0运算产生NaN。即便网格步长为0.1,受二进制浮点数存储精度的影响,仍可能出现靠近引力源点位的数值异常,导致对应位置的矢量无法渲染。 - 逻辑层面的计算偏差:原代码计算
v分量时,直接使用abs(y)作为引力距离的分母,没有结合x方向的坐标差计算网格点到两个引力源(分别位于(x1,0)、(x2,0))的实际空间距离,即便修复了除零问题,得到的矢量场也不符合双星系统的物理预期。
修复操作
- 在所有涉及引力距离计算的分母中加入极小的偏移量(如
1e-6),从根源上避免除零错误。该偏移量远小于网格步长,不会影响正常点位的计算精度。 - 使用
np.nan_to_num对计算得到的u、v数组做兜底处理,将残留的NaN、正/负无穷值替换为合法的0值,保证所有网格点位都有可渲染的矢量数据。 - 修正
v分量的引力计算逻辑,基于两点间的欧氏距离计算引力贡献,保证矢量场的物理意义正确。
修复后可直接运行的代码
import matplotlib.pyplot as plt import numpy as np # 定义极小偏移量规避除零 eps = 1e-6 X = np.arange(-2, 2, .1) Y = np.arange(-2, 2, .1) x, y = np.meshgrid(X, Y) m1 = 1 m2 = 2 x1 = 4/3 x2 = 2/3 omega = 3/8 # 计算x方向矢量分量,分母加偏移量避免除零 u = -(m1 / (abs(x - x1) + eps)**3) * (x - x1) \ - (m2 / (abs(x - x2) + eps)**3) * (x - x2) \ + x * omega # 计算y方向矢量分量,基于实际欧氏距离计算引力贡献,同步加偏移量 dist1 = np.sqrt((x - x1)**2 + y**2) + eps dist2 = np.sqrt((x - x2)**2 + y**2) + eps v = -(m1 / dist1**3) * y \ - (m2 / dist2**3) * y \ + y * omega # 过滤残留非法值 u = np.nan_to_num(u, nan=0.0, posinf=0.0, neginf=0.0) v = np.nan_to_num(v, nan=0.0, posinf=0.0, neginf=0.0) fig, ax = plt.subplots() ax.quiver(x, y, u, v) plt.show()
优化提示:如果需要调整矢量显示效果,可以通过
quiver的scale参数修改矢量长度,避免矢量重叠影响可读性。
内容的提问来源于stack exchange,提问作者Fernando Robinson
相关产品推荐
相关产品推荐

