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

Python中streamplot处理拉伸网格报错及非均匀网格场线绘制问题

磁场场线绘制问题及解答

问题描述

尝试用streamplot绘制磁场场线时,触发报错:

ValueError: 'x' values must be equally spaced

已知代码中x方向是Fourier基的均匀网格,y方向是Chebyshev基的非均匀网格,不理解为何会提示x需均匀分布。同时想了解:

  1. 如何在非均匀网格上绘制场线?
  2. 除streamplot外还有哪些场线绘制方法?

运行代码

import numpy as np
import h5py
import matplotlib.pyplot as plt

f = h5py.File('./B_mm/Re_10k/Bx_v24/Bx_v24_s1.h5', 'r')
y = f['/scales/y/1.0'][:]
x = f['/scales/x/1.0'][:]
Bxtotal = f['/tasks/Bxtotal'][:]
Bytotal = f['/tasks/Bytotal'][:]
t = f['scales']['sim_time'][:]
print(np.shape(y))
print('y = ', y)
print(np.shape(x))
print('x= ', x)

X, Y = np.meshgrid(y,x)
print(np.shape(X))
print(np.shape(Y))

Bx = Bxtotal[len(Bxtotal)-1, :, :]
By = Bytotal[len(Bytotal)-1, :, :]
print(np.shape(Bx))
print(np.shape(By))

plt.figure(figsize=(4,4),facecolor="w")
plt.streamplot(X, Y, Bx, By, color='k', density=1.3, minlength=0.9, arrowstyle='-')
plt.show()

报错信息(中文翻译)

错误信息截图

值错误:'x'值必须等间距分布


问题解答

1. 报错原因

你在调用np.meshgrid(y, x)时搞反了参数顺序:

  • 原本x是均匀网格,y是非均匀网格,但meshgrid(y, x)生成的X是基于y的网格(非均匀),Y是基于x的网格(均匀)。
  • 而streamplot函数会把第一个传入的网格参数当作x轴数据,它要求x轴方向的网格必须均匀,因此检测到非均匀的X后触发报错。

只需把meshgrid的参数顺序修正为X, Y = np.meshgrid(x, y),就能让streamplot识别到均匀的x轴网格,解决报错。

2. 非均匀网格上场线绘制方法

方法一:修正streamplot的输入(仅单方向非均匀)

如果只有一个方向是非均匀网格(比如你的场景,y方向非均匀,x方向均匀),修正meshgrid参数顺序后直接用streamplot即可——streamplot仅要求x轴方向(列维度)的网格均匀,y轴方向(行维度)支持非均匀网格。

修正后的关键代码:

X, Y = np.meshgrid(x, y)  # 交换x和y的顺序
plt.streamplot(X, Y, Bx, By, color='k', density=1.3, minlength=0.9, arrowstyle='-')

方法二:插值到均匀网格(双方向非均匀)

如果x、y方向都是非均匀网格,可以先把磁场数据插值到均匀网格上,再用streamplot:

from scipy.interpolate import griddata

# 生成均匀网格
xi = np.linspace(x.min(), x.max(), 100)
yi = np.linspace(y.min(), y.max(), 100)
Xi, Yi = np.meshgrid(xi, yi)

# 插值Bx和By
Bx_interp = griddata((x.flatten(), y.flatten()), Bx.flatten(), (Xi, Yi), method='cubic')
By_interp = griddata((x.flatten(), y.flatten()), By.flatten(), (Xi, Yi), method='cubic')

# 绘制场线
plt.streamplot(Xi, Yi, Bx_interp, By_interp, color='k')

方法三:数值积分绘制场线(完全适配非均匀网格)

直接对磁场的微分方程进行数值积分,手动生成场线,不受网格限制:

from scipy.integrate import odeint

# 定义场线的微分方程:dx/ds = Bx(x,y), dy/ds = By(x,y)
def field_line(s, pos, Bx, By, x_grid, y_grid):
    # 插值得到当前位置的磁场值
    bx = np.interp(pos[0], x_grid, np.interp(pos[1], y_grid, Bx))
    by = np.interp(pos[0], x_grid, np.interp(pos[1], y_grid, By))
    # 归一化,保证积分步长稳定
    norm = np.sqrt(bx**2 + by**2)
    return bx/norm, by/norm

# 初始化多个起始点
start_points = [[x.min() + i*(x.max()-x.min())/5, y.mean()] for i in range(6)]

plt.figure(figsize=(4,4))
for start in start_points:
    s = np.linspace(0, 10, 1000)  # 积分长度
    line = odeint(field_line, start, s, args=(Bx, By, x, y))
    plt.plot(line[:,0], line[:,1], 'k-')
plt.xlim(x.min(), x.max())
plt.ylim(y.min(), y.max())
plt.show()

3. 除streamplot外的场线绘制方法

  • matplotlib.quiver:绘制离散的矢量箭头,适合快速查看磁场的方向和大小分布,但不是连续场线。
  • Mayavi flow函数:适合3D场线绘制,天然支持非均匀网格,2D场景也可使用,可视化效果更丰富。
  • 手动数值积分:如上述方法三,完全自定义场线的起始点、积分步长和终止条件,灵活性最高,适配所有网格类型。

内容的提问来源于stack exchange,提问作者Manohar Teja

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 01:39:18