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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13781025/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 09:35:10  来源:igfitidea点击:

Matplotlib contour from xyz data: griddata invalid index

pythonmatplotlibinterpolation

提问by Napseis

I'm trying to do a contour plot using matplotlib of a file with the following format:

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

x1 y1 z1

x1 y1 z1

x2 y2 z2

x2 y2 z2

etc

等等

I can load it with numpy.loadtxt to get the vectors. So far, no trouble.

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

I read this to learn how to plot, and can reproduce it by copy paste, so i'm sure nothin is wrong with my installation:

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

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

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

I understand I have to input x and y as vector and z as an array ,which can be done with griddata. This is also what i find on this site.

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

The documentation says:

文档说:

zi = griddata(x,y,z,xi,yi) fits a surface of the form z = f*(*x, y) to the data in the (usually) nonuniformly spaced vectors (x, y, z). griddata() interpolates this surface at the points specified by (xi, yi) to produce zi. xi and yi must describe a regular grid, can be either 1D or 2D, but must be monotonically increasing.

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

For the sake of the example, I have written this code:

为了示例起见,我编写了以下代码:

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)

However, I get the following error when it comes to the griddata: IndexError: invalid index

但是,当涉及到网格数据时,我收到以下错误:IndexError: invalid index

So, I tried to modify a bit the exemple of the doc like following:

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

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

And I get the same error. I don't understand what's going wrong.

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

Thanks for your help.

谢谢你的帮助。

采纳答案by Napseis

ok, I finally found the solution to plot it. For those interested, here is the trick: use the griddata from Scipy with the 'nearest' method.

好的,我终于找到了绘制它的解决方案。对于那些感兴趣的人,这里有一个技巧:使用 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)

回答by unutbu

Consider:

考虑:

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

This means we know the z-values at certain points along the line x=y.

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

From there,

从那里,

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

is asking mlab.griddatato extrapolate the values of zfor all points in a rectangular grid.

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

We've given a lot of information about how zvaries along this line, but no information about how zvaries in the perpendicular direction (away from the x = yline). An error is being raised because mlab.griddatarefuses to guess.

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

You'll get better results if your initial x, ydata are distributed more randomly:

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

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

在此处输入图片说明



If you want mlab.griddatato extrapolate data along the line x=yto the entire grid in an arbitrary way, you could add two extra boundary points (xmin, ymax, z[0])and (xmax,ymin,z[-1]):

如果您想mlab.griddatax=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

在此处输入图片说明