使用网格将X、Y、Z三元组转换为三个二维数组,用于matplotlib中的曲面绘制



我是Python的新手,所以请耐心等待。我感谢任何帮助!

我有:三个1D列表(xr、yr、zr),一个包含x值,另两个包含y值和z值
我想做的事:在matplotlib 中创建3D等高线图

我意识到我需要使用meshgrid函数将三个1D列表转换为三个2D列表。

到目前为止,我拥有的是:

xr = np.asarray(xr) 
yr = np.asarray(yr)
zr = np.asarray(zr)
X, Y = np.meshgrid(xr,yr)
znew = np.array([zr for x,y in zip(np.ravel(X), np.ravel(Y))])
Z = znew.reshape(X.shape)

运行此操作会给我以下错误(对于我在上面输入的最后一行):

 total size of new array must be unchanged

我在斯塔科弗弗洛周围挖掘,并尝试使用有类似问题的人的建议。以下是我从这些建议中得到的错误:

将最后一行更改为:

Z = znew.reshape(X.shape[0])

给出相同的错误。

将最后一行更改为:

Z = znew.reshape(X.shape[0], len(znew))

给出错误:

Shape of x does not match that of z: found (294, 294) instead of (294, 86436).

更改为:

Z = znew.reshape(X.shape, len(znew))

给出错误:

an integer is required

有什么想法吗?

下面的示例代码适用于我的

import numpy as np
import matplotlib.pyplot as plt
xr = np.linspace(-20, 20, 100)
yr = np.linspace(-25, 25, 110)
X, Y = np.meshgrid(xr, yr)
#Z = 4*X**2 + Y**2
zr = []
for i in range(0, 110):
    y = -25.0 + (50./110.)*float(i)
    for k in range(0, 100):
        x = -20.0 + (40./100.)*float(k)
        v = 4.0*x*x + y*y
        zr.append(v)
Z = np.reshape(zr, X.shape)
print(X.shape)
print(Y.shape)
print(Z.shape)
plt.contour(X, Y, Z)
plt.show()

TL;DR

import matplotlib.pyplot as plt
import numpy as np
def get_data_for_mpl(X, Y, Z):
    result_x = np.unique(X)
    result_y = np.unique(Y)
    result_z = np.zeros((len(result_x), len(result_y)))
    # result_z[:] = np.nan
    for x, y, z in zip(X, Y, Z):
        i = np.searchsorted(result_x, x)
        j = np.searchsorted(result_y, y)
        result_z[i, j] = z
    return result_x, result_y, result_z

xr, yr, zr = np.genfromtxt('data.txt', unpack=True)
plt.contourf(*get_data_for_mpl(xr, yr, zr), 100)
plt.show()

详细答案

一开始,您需要找出要绘制图形的xy的值。这可以使用numpy.unique功能来完成:

result_x = numpy.unique(X)
result_y = numpy.unique(Y)

接下来,您需要创建一个numpy.ndarray,其中包含zip(X, Y):中每个点(x, y)的函数值

result_z = numpy.zeros((len(result_x), len(result_y)))
for x, y, z in zip(X, Y, Z):
    i = search(result_x, x)
    j = search(result_y, y)
    result_z[i, j] = z

如果数组是排序的,那么它中的搜索可以不是在线性时间中执行,而是在对数时间中执行的,所以使用numpy.searchsorted函数进行搜索就足够了。但是为了使用它,必须对数组result_xresult_y进行排序。幸运的是,排序是numpy.unique方法的一部分,没有额外的操作要做。用np.searchsorted替换search(该方法在任何地方都没有实现,只是作为中间步骤给出)方法就足够了。

最后,为了获得所需的图像,调用matplotlib.pyplot.contour matplotlib.pyplot.contourf方法就足够了。

如果result_x中的所有xresult_y中的全部y(x, y)的函数值不存在,并且您只想不绘制任何内容,那么用NaN替换缺失的值就足够了。或者,更简单地说,从NaN将result_z创建为numpy.ndarray`,然后填充:

result_z = numpy.zeros((len(result_x), len(result_y)))
result_z[:] = numpy.nan

相关内容

  • 没有找到相关文章

最新更新