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必须描述一个规则的网格,可以是一维或2D,但必须单调递增。
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
然而,当涉及到griddata时,我得到以下错误:IndexError:无效索引。
So, I tried to modify a bit the exemple of the doc like following:
所以,我试着修改了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')
And I get the same error. I don't understand what's going wrong.
结果是一样的。我不明白是怎么回事。
Thanks for your help.
谢谢你的帮助。
2 个解决方案
#1
14
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
.
这意味着我们知道x=y处的某些点的z值。
From there,
从那里,
zi = ml.griddata(x,y,z,xi,yi)
is asking mlab.griddata
to extrapolate the values of z
for all points in a rectangular grid.
是问mlab。网格数据来推断矩形网格中所有点的z值。
We've given a lot of information about how z
varies along this line, but no information about how z
varies in the perpendicular direction (away from the x = y
line). An error is being raised because mlab.griddata
refuses to guess.
我们已经给出了很多关于z在这条直线上的变化的信息,但是没有关于z如何在垂直方向上变化的信息(远离x = y线)。由于mlab的存在,出现了一个错误。griddata拒绝猜测。
You'll get better results if your initial x
, y
data 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()
If you want mlab.griddata
to extrapolate data along the line x=y
to the entire grid in an arbitrary way, you could add two extra boundary points (xmin, ymax, z[0])
and (xmax,ymin,z[-1])
:
如果你想要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()
#2
2
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)
#1
14
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
.
这意味着我们知道x=y处的某些点的z值。
From there,
从那里,
zi = ml.griddata(x,y,z,xi,yi)
is asking mlab.griddata
to extrapolate the values of z
for all points in a rectangular grid.
是问mlab。网格数据来推断矩形网格中所有点的z值。
We've given a lot of information about how z
varies along this line, but no information about how z
varies in the perpendicular direction (away from the x = y
line). An error is being raised because mlab.griddata
refuses to guess.
我们已经给出了很多关于z在这条直线上的变化的信息,但是没有关于z如何在垂直方向上变化的信息(远离x = y线)。由于mlab的存在,出现了一个错误。griddata拒绝猜测。
You'll get better results if your initial x
, y
data 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()
If you want mlab.griddata
to extrapolate data along the line x=y
to the entire grid in an arbitrary way, you could add two extra boundary points (xmin, ymax, z[0])
and (xmax,ymin,z[-1])
:
如果你想要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()
#2
2
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)