如何通过Python获取3D彩色表面?

7
如何通过Matplotlib获得以下表面?
在Matlab中很容易实现:
mesh(peaks)

似乎在Matplotlib中没有与Matlab中的mesh直接对应的方法。同时,Wireframe plots也没有colormap选项。
图片如下:enter image description here

如何使用mplot3d?http://matplotlib.org/mpl_toolkits/mplot3d/tutorial.html#wireframe-plots? - EJG89
没有一个可用的。我需要完全相同的“colormap”应用于“mesh”或“wireframe”。 - LCFactorization
你需要一个“网格”还是一个“表面”就足够了? - Justin Fletcher
网格而非表面;可以通过Matplotlib轻松实现表面绘制。 - LCFactorization
4个回答

7

当回答另一个问题时,我发现你可以使用plot_surface轻松地生成颜色映射表面,然后交换面和边的颜色:

surf = ax.plot_surface(X, Y, Z, rstride=2, cstride=2, shade=False, cmap="jet", linewidth=1)
draw()
surf.set_edgecolors(surf.to_rgba(surf._A))
surf.set_facecolors("white")
show()

产生

最终图

这种解决方案的缺点是边缘没有光滑的每像素着色,而是每个边缘只有一种颜色。


1
这在1.5.1中似乎不再起作用。以下代码可以使用:surf = ax.plot_surface(X, Y, Z, rstride=1, cstride=1, shade=False, cmap=mpl.colors.ListedColormap(['white']))m = plt.cm.ScalarMappable(surf.norm)surf.set_edgecolors(m.to_rgba(surf.get_array())) - wilywampa
@wilywampa 谢谢。你的修复对我不起作用;但是这个问题给了我提示,在plot_surface调用中添加linewidth关键字可以解决这个问题。 - Phillip
如果不想要表面后面的隐藏线条,可以使用surf.set_facecolor([0]*4)代替 'white' - herrlich10

6

使用matplotlib似乎是可行的,即使这有点像黑客行为:

from mpl_toolkits.mplot3d import axes3d
from mpl_toolkits.mplot3d import art3d
import matplotlib.pyplot as plt
import numpy as np
import matplotlib as mpl

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
X, Y, Z = axes3d.get_test_data(0.05)
wire = ax.plot_wireframe(X, Y, Z, rstride=10, cstride=10)

# Retrive data from internal storage of plot_wireframe, then delete it
nx, ny, _  = np.shape(wire._segments3d)
wire_x = np.array(wire._segments3d)[:, :, 0].ravel()
wire_y = np.array(wire._segments3d)[:, :, 1].ravel()
wire_z = np.array(wire._segments3d)[:, :, 2].ravel()
wire.remove()

# create data for a LineCollection
wire_x1 = np.vstack([wire_x, np.roll(wire_x, 1)])
wire_y1 = np.vstack([wire_y, np.roll(wire_y, 1)])
wire_z1 = np.vstack([wire_z, np.roll(wire_z, 1)])
to_delete = np.arange(0, nx*ny, ny)
wire_x1 = np.delete(wire_x1, to_delete, axis=1)
wire_y1 = np.delete(wire_y1, to_delete, axis=1)
wire_z1 = np.delete(wire_z1, to_delete, axis=1)
scalars = np.delete(wire_z, to_delete)

segs = [list(zip(xl, yl, zl)) for xl, yl, zl in \
                 zip(wire_x1.T, wire_y1.T, wire_z1.T)]

# Plots the wireframe by a  a line3DCollection
my_wire = art3d.Line3DCollection(segs, cmap="hsv")
my_wire.set_array(scalars)
ax.add_collection(my_wire)

plt.colorbar(my_wire)
plt.show()

enter image description here


1

0

目前的matplotlib 1.3.1似乎无法处理这种mesh图或进一步的PDF导出。在matplotlib有进一步更新之前,gnuplot.pygnuplot.py 1.8可能是一个选择。

以下是通过gnuplot创建的示例: mesh

MayaVI2不支持PDF导出,但也是另一个不错的选择。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接