【问题标题】:Matplotlib contour from xyz data: griddata invalid index来自 xyz 数据的 Matplotlib 轮廓:griddata 无效索引
【发布时间】:2015-06-25 10:17:27
【问题描述】:

我正在尝试使用以下格式的文件的 matplotlib 绘制等高线图:

x1 y1 z1

x2 y2 z2

我可以用 numpy.loadtxt 加载它来获取向量。到目前为止,没有问题。

我阅读这篇文章是为了学习如何绘图,并且可以通过复制粘贴来重现它,所以我确信我的安装没有任何问题:

http://matplotlib.org/examples/pylab_examples/griddata_demo.html

我知道我必须输入 x 和 y 作为向量和 z 作为数组,这可以通过 griddata 来完成。这也是我在这个网站上找到的。

文档说:

zi = griddata(x,y,z,xi,yi) 将 z = f*(*x, y) 形式的曲面拟合到(通常)非均匀间隔向量 (x, y, z )。 griddata() 在 (xi, yi) 指定的点处对该曲面进行插值以生成 zi。 xi 和 yi 必须描述一个规则网格,可以是 1D 或 2D,但必须是单调递增的。

为了举例,我写了这段代码:

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.mlab as ml

x=np.linspace(1.,10.,20)
y=np.linspace(1.,10.,20)
z=np.linspace(1.,2.,20)

xi=np.linspace(1.,10.,10)
yi=np.linspace(1.,10.,10)

zi = ml.griddata(x,y,z,xi,yi)

但是,当涉及到 griddata 时,我收到以下错误: IndexError: 无效索引

因此,我尝试对文档的示例进行一些修改,如下所示:

from matplotlib.mlab import griddata
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(-2.1,2.1,300)
y = np.linspace(-2.1,2.1,300)
z = x*np.exp(-x**2-y**2)
# define grid.
xi = np.linspace(-2.1,2.1,100)
yi = np.linspace(-2.1,2.1,200)
# grid the data.
zi = griddata(x,y,z,xi,yi,interp='linear')

我得到同样的错误。我不明白出了什么问题。

感谢您的帮助。

【问题讨论】:

    标签: python matplotlib interpolation


    【解决方案1】:

    考虑:

    x = np.linspace(1., 10., 20)
    y = np.linspace(1., 10., 20)
    z = np.linspace(1., 2., 20)
    

    这意味着我们知道x=y 沿线某些点的 z 值。

    从那里,

    zi = ml.griddata(x,y,z,xi,yi)
    

    要求mlab.griddata 为矩形网格中的所有点推断z 的值。

    我们提供了很多关于z 如何沿这条线变化的信息,但没有关于z 如何在垂直方向(远离x = y 线)变化的信息。由于mlab.griddata 拒绝猜测,因此引发错误。

    如果您的初始xy 数据分布更随机,您将获得更好的结果:

    import numpy as np
    import matplotlib.pyplot as plt
    import matplotlib.mlab as ml
    
    ndata = 10
    ny, nx = 100, 200
    xmin, xmax = 1, 10
    ymin, ymax = 1, 10
    # x = np.linspace(1, 10, ndata)
    # y = np.linspace(1, 10, ndata)
    
    x = np.random.randint(xmin, xmax, ndata)
    y = np.random.randint(ymin, ymax, ndata)
    z = np.random.random(ndata)
    
    xi = np.linspace(xmin, xmax, nx)
    yi = np.linspace(ymin, ymax, ny)
    zi = ml.griddata(x, y, z, xi, yi)
    
    plt.contour(xi, yi, zi, 15, linewidths = 0.5, colors = 'k')
    plt.pcolormesh(xi, yi, zi, cmap = plt.get_cmap('rainbow'))
    
    plt.colorbar() 
    plt.scatter(x, y, marker = 'o', c = 'b', s = 5, zorder = 10)
    plt.xlim(xmin, xmax)
    plt.ylim(ymin, ymax)
    plt.show()
    


    如果您希望mlab.griddata 以任意方式将沿线x=y 的数据外推到整个网格,您可以添加两个额外的边界点(xmin, ymax, z[0])(xmax,ymin,z[-1])

    import numpy as np
    import matplotlib.pyplot as plt
    import matplotlib.mlab as ml
    
    np.random.seed(8)
    ndata = 10
    ny, nx = 100, 200
    xmin, xmax = 1, 10
    ymin, ymax = 1, 10
    x = np.linspace(1, 10, ndata)
    y = np.linspace(1, 10, ndata)
    z = np.random.random(ndata)
    x = np.r_[x,xmin,xmax]
    y = np.r_[y,ymax,ymin]
    z = np.r_[z,z[0],z[-1]]
    xi = np.linspace(xmin, xmax, nx)
    yi = np.linspace(ymin, ymax, ny)
    
    
    # Requires installation of natgrid
    # http://sourceforge.net/projects/matplotlib/files/matplotlib-toolkits/
    zi = ml.griddata(x, y, z, xi, yi, interp='nn')
    
    # Or, without natgrid:
    # zi = ml.griddata(x, y, z, xi, yi, interp='linear')
    
    plt.contour(xi, yi, zi, 15, linewidths = 0.5, colors = 'k')
    plt.pcolormesh(xi, yi, zi, cmap = plt.get_cmap('rainbow'))
    
    plt.colorbar() 
    plt.scatter(x, y, marker = 'o', c = 'b', s = 10, zorder = 10)
    plt.xlim(xmin, xmax)
    plt.ylim(ymin, ymax)
    plt.show()
    

    【讨论】:

    • 这是一种奇怪的行为,我很确定 Matlab 不会抱怨这一点。 scipy.interpolate.griddata 与最近的方法一起工作正常,但重新调整向量。那么,是否有内置函数可以从向量 z 中生成一个可以被 contour() 接受的矩阵?我运行模拟的网格是常规的,所以如果我明白你的意思,我将无法使用 griddata...
    • 感谢您的帮助,您的方法也适用于我想做的事情,并允许我用 mlab.griddata 指出我的错误。
    • 这个例子不适合我,使用baseMap。它还需要以下行:xi, yi = np.meshgrid(xi, yi)
    【解决方案2】:

    好的,我终于找到了绘制它的解决方案。对于那些感兴趣的人,这里有诀窍:使用 Scipy 中的 griddata 和“最近”方法。

    from scipy.interpolate import griddata
    import numpy as np
    import matplotlib.pyplot as plt
    x=np.linspace(1.,10.,20)
    y=np.linspace(1.,10.,20)
    z=z = np.random.random(20)
    xi=np.linspace(1.,10.,10)
    yi=np.linspace(1.,10.,10)
    
    X,Y= np.meshgrid(xi,yi)
    Z = griddata((x, y), z, (X, Y),method='nearest')
    plt.contourf(X,Y,Z)
    

    【讨论】:

      猜你喜欢
      • 2022-06-14
      • 1970-01-01
      • 1970-01-01
      • 2015-05-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-24
      相关资源
      最近更新 更多