【问题标题】:How to make a matrix out of existing xyz data如何用现有的 xyz 数据制作矩阵
【发布时间】:2016-12-09 12:03:42
【问题描述】:

我想使用 matplotlib.pyplot.pcolormesh 绘制深度图。

我有一个 xyz 文件 三列,即 x(lat)、y(lon)、z(dep)。

所有列的长度相同

pcolormesh 需要矩阵作为输入。 所以使用 numpy.meshgrid 我可以将 x 和 y 转换为矩阵:

xx,yy = numpy.meshgrid(x_data,y_data)

这很好用...但是,我不知道如何创建深度 (z) 数据的矩阵... 如何为我的 z_data 创建与我的 x_data 和 y_data 矩阵相对应的矩阵?

【问题讨论】:

  • 你想要一个 3d 矩阵吗?因为 numpy 支持 n 维矩阵
  • 您的x,y,z 的大小是多少? x 的每个值或xy 的笛卡尔积是否有一个z 值。那是len(z)==len(x)==len(y) 还是len(z)==len(x)*len(y)
  • 有效问题,每个 x,y 组合都有一个 z 值
  • @HenryPrickett-Morgan 我不这么认为......这是一个 2d xy 图,我希望它们根据我的 z 值进行颜色编码。我想使用 matplotlib 模块中的 pcolormesh 方法

标签: python numpy matrix matplotlib coordinates


【解决方案1】:

根据您是否生成z,您至少有两个不同的选项。

如果您正在生成 z(例如,您知道它的公式),这非常容易(参见下面的 method_1())。

如果您只有 (x,y,z) 元组的列表,那就更难了(请参阅下面的method_2(),也许还有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)

方法一:生成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

如果你没有那个能力,并且得到一个固定的(x,y,z)。您可以执行以下操作。首先,我定义了一个生成假数据的函数:

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

这里,返回的矩阵如下:

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:
#   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) 的设置方式。这个选项需要两件事:

  1. 不同 x 样本位置的数量等于不同 y 样本位置的数量。
  2. 对于每个可能的唯一 (x,y) 对,您的数据中都有一个对应的 (x,y,z)。

因此,(x,y,z) 对的数量必须等于唯一 x 点数量的平方(其中唯一 x 位置的数量等于唯一 y 位置的数量)。

一般来说,对于采样数据,这不会为真。但如果是,您可以避免插值:

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

【讨论】:

  • Tnx !我会看看它。为了回答你的问题,我的所有数据都是固定的。
  • 嘿,再次感谢您。我正在尝试选项二……但我不确定如何生成假数据。我的意思是,我知道语法是如何工作的,但是我应该以任何特定的方式生成它吗?请您再详细说明一下吗?
  • @J.A.Cado 当然,很抱歉造成混乱。 生成了假数据,因为我没有你的。您不需要,只需使用您的真实数据。您唯一需要注意的是您的数据排列方式相似(请参阅“这里,返回的矩阵看起来像:”下的几行)。
  • 天哪,我做到了!棒极了!非常感谢 :D 只是一个小问题,我正在使用 pandas 数据框,并且只是在 scypy.griddata 方法中加载数据框的列。 girddata((df['x'],df['y']),df['z'],(X,Y),method='linear')但这从来没有奏效,它给了我关于尺寸不正确的错误。知道为什么那行不通吗?干杯!
  • 选项 2 对我有用 我有自己的数据集,其中包含来自现场的实际数据。列 (x,y,z) 的长度都相等。并且每个 (x,y,z) 对都是唯一的,
猜你喜欢
  • 2013-02-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-08
  • 2014-05-10
  • 2012-11-17
  • 1970-01-01
相关资源
最近更新 更多