如何在Python中绘制3D图?
这是MATLAB版本的3D绘图代码:
编辑:
这是当前的代码:
plt.figure(2)
fig_b = Axes3D(fig2)
xx2 = np.arange(0, L+h_grid*L, h_grid*L)
yy2 = np.arange(-b, b+h_grid*b, h_grid*b)
X, Y = np.meshgrid(xx2, yy2)
W = np.zeros((41,21), float)
mx = len(xx2)*len(yy2)
X = np.reshape(X, (1, mx))
Y = np.reshape(Y, (1, mx))
W = np.reshape(W, (1, mx))
for j in range(0, mx):
W[0][j] = np.sin(np.pi*X[0][j]/L)
surf = fig_b.plot_surface(X, Y, W, rstride=1, cstride=1, cmap=cm.jet, linewidth=0, antialiased=False) # This is the line number 168
plt.xlabel('x')
plt.ylabel('y')
这是我收到的错误信息:
Traceback (most recent call last):
File "nonhomog.py", line 247, in <module>
main()
File "nonhomog.py", line 245, in main
nonhomog(nu)
File "nonhomog.py", line 168, in nonhomog
surf = fig_b.plot_surface(X, Y, W, rstride=1, cstride=1, cmap=cm.jet, linewidth=0, antialiased=False)
File "/usr/lib/pymodules/python2.6/mpl_toolkits/mplot3d/axes3d.py", line 618, in plot_surface
polyc = art3d.Poly3DCollection(polys, *args, **kwargs)
File "/usr/lib/pymodules/python2.6/mpl_toolkits/mplot3d/art3d.py", line 290, in __init__
PolyCollection.__init__(self, verts, *args, **kwargs)
File "/usr/lib/pymodules/python2.6/matplotlib/collections.py", line 668, in __init__
self.set_verts(verts, closed)
File "/usr/lib/pymodules/python2.6/mpl_toolkits/mplot3d/art3d.py", line 312, in set_verts
self.get_vector(verts)
File "/usr/lib/pymodules/python2.6/mpl_toolkits/mplot3d/art3d.py", line 305, in get_vector
xs, ys, zs = zip(*points)
ValueError: need more than 0 values to unpack
2 个回答
4
你遇到什么问题了?你试图把一个不是数字的东西变成负数。换句话说,AxesSubplot(这是什么东西呢?)不支持一元负号操作。
所以,你的代码不能合理地被称为“你所做的”,因为在这段代码里你根本没有定义b
,但它却存在,并且是一个叫AxesSubplot
的自定义类型。如果你能解释一下AxesSubplot是什么,那会很有帮助。如果可能的话,试着提供一些实际的代码来展示这个问题。
编辑:正如DSM所指出的,你覆盖了你的b变量。问题在于你陷入了“数学模式”,使用了像“a”、“b”和“M”这样的不具描述性的变量名。建议使用更长、更具描述性的名字。
与其这样:
a = fig.add_subplot(2,2,i)
b = fig2.add_subplot(2,2,i)
不如这样:
x_subplot = fig.add_subplot(2,2,i)
y_subplot = fig2.add_subplot(2,2,i)
或者类似的东西(我不太确定这个变量实际上是什么,所以这只是个例子)。
4
在为X和Y设置好网格后,你需要为Z值创建一个网格。
我在代码中目前是这样做的:
# [ (x1, y1, z1), (x2, y2, z2), ... (xN, yN, zN) ]
all_vals = ...
# (x1, x2, ... xN) , (y1, y2, ... yN) , (z1, z2, ... zN)
all_xvals, all_yvals, all_zvals = zip(*all_vals)
fig = plt.figure()
ax = Axes3D(fig)
X, Y = np.meshgrid(xvals, yvals)
# This is the part you want:
Z1 = np.zeros(X.shape, float)
for (x, y, z) in all_vals:
x = find_in_sorted_list(x, xvals)
y = find_in_sorted_list(y, yvals)
Z1[y,x] = z
surf = ax.plot_surface(X, Y, Z1, rstride=1, cstride=1, cmap=cm.jet,
linewidth=0, antialiased=False)
plt.xlabel('Blur standard deviation')
plt.ylabel('JPEG quality')
ax.w_zaxis.set_major_locator(LinearLocator(10))
ax.w_zaxis.set_major_formatter(FormatStrFormatter('%.03f'))
fig.colorbar(surf, shrink=0.5, aspect=5)
plt.show()
这样我就得到了一个看起来像这样的图:
我把它保存成了一个文件,但当你调用 plt.show()
时,会出现一个互动窗口,你可以随意改变视角。