我是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()
详细答案
一开始,您需要找出要绘制图形的x
和y
的值。这可以使用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_x
和result_y
进行排序。幸运的是,排序是numpy.unique
方法的一部分,没有额外的操作要做。用np.searchsorted
替换search
(该方法在任何地方都没有实现,只是作为中间步骤给出)方法就足够了。
最后,为了获得所需的图像,调用matplotlib.pyplot.contour
或 matplotlib.pyplot.contourf
方法就足够了。
如果result_x
中的所有x
和result_y
中的全部y
的(x, y)
的函数值不存在,并且您只想不绘制任何内容,那么用NaN替换缺失的值就足够了。或者,更简单地说,从NaN将result_z
创建为numpy.ndarray`,然后填充:
result_z = numpy.zeros((len(result_x), len(result_y)))
result_z[:] = numpy.nan