How to obtain the following surface via Matplotlib?
It is easy in matlab via:
mesh(peaks)
It seems matplotlib does not have an exact counterpart of mesh
in matlab.
the Wireframe plots
does not have any colormap
option
Creating 3D surface Plot The axes3d present in Matplotlib's mpl_toolkits. mplot3d toolkit provides the necessary functions used to create 3D surface plots. Surface plots are created by using ax. plot_surface() function.
The ax. contour3D() function creates three-dimensional contour plot. It requires all the input data to be in the form of two-dimensional regular grids, with the Z-data evaluated at each point.
Simple 3D Mesh example go. Mesh3d draws a 3D set of triangles with vertices given by x , y and z . If only coordinates are given, an algorithm such as Delaunay triangulation is used to draw the triangles. Otherwise the triangles can be given using the i , j and k parameters (see examples below).
While answering another question I found that you can easily do this using plot_surface
to produce a color mapped surface, and then exchanging face and edge colors:
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()
produces
The disadvantage this solution has over the other one is that the edges do not have smooth, per-pixel colouring, but one single color each.
It seems to be possible with matplotlib even if it is a bit of a hack:
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()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With