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

Matplotlib等高线图变量范围变更致图形不一致问题问询

Matplotlib等高线图变量范围变更后图形不匹配问题

问题现象

使用同一函数绘制等高线图时,仅扩大其中一个变量的取值范围(新范围包含旧范围),得到的等高线图无法与原图形对应,重叠后也存在明显偏差。即使使用简单的二次函数测试,该问题依然存在。

相关代码

核心函数定义

import numpy as np
from scipy.integrate import solve_ivp
import matplotlib.pyplot as plt

tData = np.linspace(0,2,11)
yData = np.array([0.99, 0.81, 0.71, 0.55, 0.50, 0.42, 0.24, 0.32, 0.17, 0.26, 0.19])
def dydt(t,y,beta):
    return -beta*y

def funD(y0, beta, tData, yData):
    res = solve_ivp(dydt, [tData[0],tData[-1]], [y0], t_eval=tData, args=(beta,),rtol=1e-6, method='RK45')
    err = 0
    for i in range(tData.shape[0]):
        err = err + (yData[i]-res.y[0,i])**2
    return err

第一次绘图(beta范围0-2)

ygrid = np.linspace(0,2,100)
betagrid = np.linspace(0,2,100)
z = np.ones((100,100))
for i in range(100):
    for j in range(100):
        z[i,j] = funD(ygrid[i], betagrid[j], tData, yData)
fig, ax = plt.subplots()
cnt = ax.contour(ygrid,betagrid,z,1000)

第二次绘图(beta范围0-4)

ygrid = np.linspace(0,2,100)
betagrid = np.linspace(0,4,100)
z = np.ones((100,100))
for i in range(100):
    for j in range(100):
        z[i,j] = funD(ygrid[i], betagrid[j], tData, yData)
fig, ax = plt.subplots()
cnt = ax.contour(ygrid,betagrid,z,1000)

重叠绘图测试

ygrid = np.linspace(0,2,100)
betagrid = np.linspace(0,2,100)
z = np.ones((100,100))
for i in range(100):
    for j in range(100):
        z[i,j] = funD(ygrid[i], betagrid[j], tData, yData)
        
ygrid1 = np.linspace(0,2,100)
betagrid1 = np.linspace(0,4,100)
z1 = np.ones((100,100))
for i in range(100):
    for j in range(100):
        z1[i,j] = funD(ygrid1[i], betagrid1[j], tData, yData)
fig, ax = plt.subplots()
cnt = ax.contour(ygrid,betagrid,z,100)
cnt1 = ax.contour(ygrid,betagrid,z1,100,alpha=0.5)

简单函数复现测试

def func(x,y):
    return x**2+y**2

ygrid = np.linspace(0,2,100)
betagrid = np.linspace(0,2,100)
z = np.ones((100,100))
for i in range(100):
    for j in range(100):
        z[i,j] = func(ygrid[i], betagrid[j])
        
ygrid1 = np.linspace(0,2,100)
betagrid1 = np.linspace(0,4,100)
z1 = np.ones((100,100))
for i in range(100):
    for j in range(100):
        z1[i,j] = func(ygrid1[i], betagrid1[j])
fig, ax = plt.subplots()
cnt = ax.contour(ygrid,betagrid,z,100)
cnt1 = ax.contour(ygrid,betagrid,z1,100,alpha=0.5)

问题原因

  • 坐标与z数组不匹配:重叠绘图时,基于betagrid1(0-4)生成的z1被错误地与原betagrid(0-2)配对。z1的列对应betagrid1的0-4取值,而原betagrid仅覆盖0-2,这导致z1中对应beta2-4的列被强行映射到beta0-2的坐标区间,图形必然错位。
  • 等高线层级自动变化:contour函数默认根据z数组的全局极值自动划分等高线层级。扩大beta范围后,z1的取值范围改变,层级划分也随之变化,即使坐标正确,线条也无法和原图形重合。

解决方案

1. 对齐坐标与z数组

截取z1中对应beta0-2的部分,确保和原betagrid的范围匹配:

# betagrid1是0-4共100点,前50点对应0-2
z1_cut = z1[:, :50]
fig, ax = plt.subplots()
cnt = ax.contour(ygrid, betagrid, z, 100)
cnt1 = ax.contour(ygrid, betagrid, z1_cut, 100, alpha=0.5)

2. 固定等高线层级

手动指定统一的等高线层级范围,保证两次绘图使用相同的levels:

# 基于原z数组的极值生成统一层级
levels = np.linspace(z.min(), z.max(), 100)

fig, ax = plt.subplots()
cnt = ax.contour(ygrid, betagrid, z, levels=levels)
cnt1 = ax.contour(ygrid, betagrid, z1[:, :50], levels=levels, alpha=0.5)

3. 优化网格数据生成

用np.meshgrid和向量化操作替代嵌套循环,提升效率且减少错误:

ygrid, betagrid = np.meshgrid(np.linspace(0,2,100), np.linspace(0,2,100))
vec_funD = np.vectorize(funD)
z = vec_funD(ygrid, betagrid, tData, yData)

内容的提问来源于stack exchange,提问作者Asking Questions

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 15:00:01