Hi Byron,
This is a bit of a workaround, but you can specify facecolors explicitly by creating a triangulation of your surface explicitly and creating a Poly3DCollection with these facecolors. I’m attaching an example below which is a modified version of the plot_trisurf demo [1] in the matplotlib documentation. It showcases both random colors and a smooth gradient (the latter in the line that’s commented out).
I would have thought that it should be possible to pass an argument like “facecolors” to plot_trisurf directly, since the documentation [2] states that “other arguments are passed on to Poly3DCollection”. However, I couldn’t get this to work quickly. Maybe someone else knows how?
Best regards,
Max
[1] http://matplotlib.org/examples/mplot3d/trisurf3d_demo.html
[2] http://matplotlib.org/mpl_toolkits/mplot3d/api.html
from mpl_toolkits.mplot3d import Axes3D
from matplotlib import cm
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.tri import Triangulation
from mpl_toolkits.mplot3d.art3d import Poly3DCollection
n_angles = 36
n_radii = 8
An array of radii
Does not include radius r=0, this is to eliminate duplicate points
radii = np.linspace(0.125, 1.0, n_radii)
An array of angles
angles = np.linspace(0, 2*np.pi, n_angles, endpoint=False)
Repeat all angles for each radius
angles = np.repeat(angles[…,np.newaxis], n_radii, axis=1)
Convert polar (radii, angles) coords to cartesian (x, y) coords
(0, 0) is added here. There are no duplicate points in the (x, y) plane
x = np.append(0, (radii*np.cos(angles)).flatten())
y = np.append(0, (radii*np.sin(angles)).flatten())
Pringle surface
z = np.sin(-x*y)
tri = Triangulation(x, y) # NOTE: This assumes that there is a nice projection of the surface into the x/y-plane!
triangle_vertices = np.array([np.array([[x[T[0]], y[T[0]], z[T[0]]],
[x[T[1]], y[T[1]], z[T[1]]],
[x[T[2]], y[T[2]], z[T[2]]]]) for T in tri.triangles])
midpoints = np.average(triangle_vertices, axis=1)
def find_color_for_point(pt):
x, y, z = pt
col = [(y+1)/2, (1-y)/2, 0]
return col
#facecolors = [find_color_for_point(pt) for pt in midpoints] # smooth gradient
facecolors = [np.random.random(3) for pt in midpoints] # random colors
coll = Poly3DCollection(triangle_vertices, facecolors=facecolors, edgecolors=‘black’)
fig = plt.figure()
ax = fig.gca(projection=‘3d’)
ax.add_collection(coll)
ax.set_xlim(-1, 1)
ax.set_ylim(-1, 1)
ax.set_zlim(-1, 1)
ax.elev = 50
plt.show()