问题描述
我想使用matplotlib.pyplot.pcolormesh绘制深度图.
I want to use matplotlib.pyplot.pcolormesh to plot a depth plot.
我有一个xyz文件三列,即x(lat),y(lon),z(dep).
What I have is a xyz fileThree columns i.e. x(lat), y(lon), z(dep).
所有列的长度相等
pcolormesh需要矩阵作为输入.因此,使用numpy.meshgrid,我可以将x和y转换为矩阵:
pcolormesh require matrices as input.So using numpy.meshgrid I can transform the x and y into matrices:
xx,yy = numpy.meshgrid(x_data,y_data)
这很好用...但是,我不知道如何创建我的深度(z)数据的矩阵...如何为z_data创建与x_data和y_data矩阵相对应的矩阵?
This works great...However, I don't know how to create Matrix of my depth (z) data...How do I create a matrix for my z_data that corresponds to my x_data and y_data matrices?
推荐答案
根据是否生成z
,您至少有两个不同的选择.
Depending on whether you're generating z
or not, you have at least two different options.
如果要生成z
(例如,您知道它的公式),则非常简单(请参见下面的method_1()
).
If you're generating z
(e.g. you know the formula for it) it's very easy (see method_1()
below).
如果仅列出(x
,y
,z
)个元组,则难度会更大(请参见下面的method_2()
,也许还有method_3()
).
If you just have just a list of (x
,y
,z
) tuples, it's harder (see method_2()
below, and maybe method_3()
).
常量
# min_? is minimum bound, max_? is maximum bound,
# dim_? is the granularity in that direction
min_x, max_x, dim_x = (-10, 10, 100)
min_y, max_y, dim_y = (-10, 10, 100)
方法1:生成z
Method 1: Generating z
# Method 1:
# This works if you are generating z, given (x,y)
def method_1():
x = np.linspace(min_x, max_x, dim_x)
y = np.linspace(min_y, max_y, dim_y)
X,Y = np.meshgrid(x,y)
def z_function(x,y):
return math.sqrt(x**2 + y**2)
z = np.array([z_function(x,y) for (x,y) in zip(np.ravel(X), np.ravel(Y))])
Z = z.reshape(X.shape)
plt.pcolormesh(X,Y,Z)
plt.show()
哪个会生成以下图形:
这相对容易,因为您可以在任意位置生成z
.
This is relatively easy, since you can generate z
at whatever points you want.
如果您没有该能力,则会获得固定的(x,y,z)
.您可以执行以下操作.首先,我定义一个生成假数据的函数:
If you don't have that ability, and are given a fixed (x,y,z)
. You could do the following. First, I define a function that generates fake data:
def gen_fake_data():
# First we generate the (x,y,z) tuples to imitate "real" data
# Half of this will be in the + direction, half will be in the - dir.
xy_max_error = 0.2
# Generate the "real" x,y vectors
x = np.linspace(min_x, max_x, dim_x)
y = np.linspace(min_y, max_y, dim_y)
# Apply an error to x,y
x_err = (np.random.rand(*x.shape) - 0.5) * xy_max_error
y_err = (np.random.rand(*y.shape) - 0.5) * xy_max_error
x *= (1 + x_err)
y *= (1 + y_err)
# Generate fake z
rows = []
for ix in x:
for iy in y:
z = math.sqrt(ix**2 + iy**2)
rows.append([ix,iy,z])
mat = np.array(rows)
return mat
在这里,返回的矩阵如下:
Here, the returned matrix looks like:
mat = [[x_0, y_0, z_0],
[x_1, y_1, z_1],
[x_2, y_2, z_2],
...
[x_n, y_n, z_n]]
方法2:在常规网格上插入给定的z
点
Method 2: Interpolating given z
points over a regular grid
# Method 2:
# This works if you have (x,y,z) tuples that you're *not* generating, and (x,y) points
# may not fall evenly on a grid.
def method_2():
mat = gen_fake_data()
x = np.linspace(min_x, max_x, dim_x)
y = np.linspace(min_y, max_y, dim_y)
X,Y = np.meshgrid(x, y)
# Interpolate (x,y,z) points [mat] over a normal (x,y) grid [X,Y]
# Depending on your "error", you may be able to use other methods
Z = interpolate.griddata((mat[:,0], mat[:,1]), mat[:,2], (X,Y), method='nearest')
plt.pcolormesh(X,Y,Z)
plt.show()
此方法产生以下图形:
错误= 0.2
错误= 0.8
方法3:不插值(对采样数据有约束)
还有第三个选项,具体取决于您的(x,y,z)
的设置方式.此选项需要两件事:
There's a third option, depending on how your (x,y,z)
is set up. This option requires two things:
- 不同的x个采样位置的数量等于不同的y个采样位置的数量.
- 对于每个可能的唯一(x,y)对,您的数据中都有一个对应的(x,y,z).
由此,(x,y,z)
对的数量必须等于唯一x点数量的平方(其中唯一x位数量等于唯一y位数量).
From this, it follows that the number of (x,y,z)
pairs must be equal to the square of the number of unique x points (where the number of unique x positions equals the number of unique y positions).
通常,对于采样数据,此不会为真.但如果是这样,则可以避免插值:
In general, with sampled data, this will not be true. But if it is, you can avoid having to interpolate:
def method_3():
mat = gen_fake_data()
x = np.unique(mat[:,0])
y = np.unique(mat[:,1])
X,Y = np.meshgrid(x, y)
# I'm fairly sure there's a more efficient way of doing this...
def get_z(mat, x, y):
ind = (mat[:,(0,1)] == (x,y)).all(axis=1)
row = mat[ind,:]
return row[0,2]
z = np.array([get_z(mat,x,y) for (x,y) in zip(np.ravel(X), np.ravel(Y))])
Z = z.reshape(X.shape)
plt.pcolormesh(X,Y,Z)
plt.xlim(min(x), max(x))
plt.ylim(min(y), max(y))
plt.show()
错误= 0.2
错误= 0.8
这篇关于如何用现有的xyz数据制作矩阵的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!