来自xyz数据的Matplotlib轮廓:griddata无效索引

时间:2012-12-08 19:24:31

标签: python matplotlib interpolation

我正在尝试使用具有以下格式的文件的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:索引无效

所以,我试着稍微修改一下doc这样的例子:

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')

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

感谢您的帮助。

2 个答案:

答案 0 :(得分:16)

考虑:

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()

enter image description here


如果您希望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()

enter image description here

答案 1 :(得分:5)

好吧,我终于找到了绘制它的解决方案。对于那些感兴趣的人,这里有一个技巧:使用Scipy的griddata和'nearest'方法。

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)