我有一个名为funcPower3的函数,正文如下所示。我想在MatplotLib中使用3D绘图功能绘制此函数。我在使用meshgrid的scipy docs上看到了一个例子。但是,在此示例中,函数不是已定义的函数,而是简单的数学运算:
fig = plt.figure()
ax = fig.gca(projection='3d')
X = np.arange(-5, 5, 0.25)
Y = np.arange(-5, 5, 0.25)
X, Y = np.meshgrid(X, Y)
R = np.sqrt(X**2 + Y**2)
Z = np.sin(R)
surf = ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap=cm.jet,
linewidth=0, antialiased=False)
我从这个示例中获取灵感,但我自己的函数签名与meshgrid中的数据不兼容。我有这个错误:
ValueError: zero-size array to minimum.reduce without identity
我的功能代码在这里:
def funcPower3(PARAM):
inputX1 = open("power3X.txt","r")
inputY = open("power3Y.txt","r")
X1=[]
Y=[]
for line in inputX1:
X1.append(float(line))
for line in inputY:
Y.append(float(line))
resTmp_ = 0
res = 0
for i in range(len(X1)):
resTmp_ = Y[i] - (PARAM[0]*(X1[i])**float(PARAM[1]))
res += resTmp_**2
return res
用于绘制3d此函数的代码在这里:
xmin = 0 ymin = 0 xmax = 10 ymax = 1
fig = plt.figure('Power 3')
ax = fig.gca(projection='3d')
Z = []
Xpl = numpy.arange(xmin, xmax, 0.1).tolist()
Ypl = numpy.arange(ymin, ymax, 0.01).tolist()
Xpl, Ypl = numpy.meshgrid(Xpl, Ypl)
Z=[]
for i in range(len(Xpl[0])):
for j in range(len(Xpl)):
Z.append(funcPower3([Xpl[j][i],Ypl[j][i]]))
surf=ax.plot_surface(Xpl, Ypl, Z, rstride=8, cstride=8, alpha=0.3,cmap=cm.jet)
ax.set_xlabel('X Label')
ax.set_ylabel('Y Label')
plt.show()
感谢和问候任何建议; ))
答案 0 :(得分:4)
引自plot_surface
documentation:
X,Y,Z:数据值为2D数组
但是你的Z
是1维的。您需要对其进行重新整形以匹配X
和Y
值。这应该有效:
Xpl = numpy.arange(xmin, xmax, 0.1).tolist()
Ypl = numpy.arange(ymin, ymax, 0.01).tolist()
Xpl, Ypl = numpy.meshgrid(Xpl, Ypl)
Z=[]
for j in range(len(Xpl)):
for i in range(len(Xpl[0])):
# your loop order was backwards
Z.append(funcPower3([Xpl[j][i],Ypl[j][i]]))
# reshape Z
Z = numpy.array(Z).reshape(Xpl.shape)
fig = plt.figure('Power 3')
ax = fig.gca(projection='3d')
surf=ax.plot_surface(Xpl, Ypl, Z, rstride=8, cstride=8, alpha=0.3,cmap=cm.jet)
ax.set_xlabel('X Label')
ax.set_ylabel('Y Label')
plt.show()
但是你的代码存在一些缺陷。首先,查看您的funcPower3
函数,您正在为每个函数调用一遍又一遍地读取两个文件。这太浪费了。而是读取这些参数一次,并将它们作为参数提供给您的函数。此函数也可以简化一点(并尝试遵循PEP8命名约定):
def func_power_3(param, x1, y):
p1, p2 = param
res = sum(y_i - (p1*x1_i)**p2 for x1_i, y_i in zip(x1, y))
return res
其余的将是
with open("power3X.txt","r") as infile:
x1 = [float(line) for line in infile]
with open("power3Y.txt","r") as infile:
y = [float(line) for line in infile]
xpl = numpy.arange(xmin, xmax, 0.1) # no need for .tolist()
ypl = numpy.arange(ymin, ymax, 0.01) # meshgrid can work with numpy.array's
xpl, ypl = numpy.meshgrid(xpl, ypl)
# we can form z with list comprehension
z = [[func_power_3([p1,p2], x1, y) for p1, p2 in zip(p1row, p2row)]
for p1row, p2row in zip(xpl, ypl)]
fig = plt.figure('Power 3')
ax = fig.gca(projection='3d')
surf=ax.plot_surface(xpl, ypl, z, rstride=8, cstride=8, alpha=0.3,cmap=cm.jet)
ax.set_xlabel('X Label')
ax.set_ylabel('Y Label')
plt.show()