From: Byron K. B. <bkb...@be...> - 2015-01-21 17:06:40
|
Thanks. This looks like it might work for me. I got your example to work, but I still need to figure out how to apply it to my problem. In particular there is the note about your Triangulation line which says that we assume there is a nice projection of the surface into the x/y-plane. Is this just a requirement of the Triangulation function or of the Poly3Dcollection? My surfaces are typically enclosed bodies, but since they’re meshed for the Electromagnetic Simulation I already know the connectivity of the vertices. Also, in your example it appears that you define one color per triangle but the trisurf files I have consist of one color per vertex. Will I need to come up with my own function for defining facecolors based on the three color values associated with each of my triangles? Byron Boulton From: Maximilian Albert [mailto:max...@gm...] Sent: Wednesday, January 21, 2015 11:03 AM To: Byron K. Boulton Cc: mat...@li... Subject: Re: [matplotlib-devel] trisurf plots with independent color data 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<http://cp.mcafee.com/d/avndygscxNJ5xd5VZN5ZwTsSztcQsFzCn4kjqdQPhOCepssKrhKCqekNPbyapJ6WpEVj7cK3HCO1kxlI-to0ExYoOYD8Y_BPp3UNBVehV_bCZd7a5Di33_nVNcQsTu7tuVtdBZXAkhP3aqvbnjIyCGyyeVkffGhBrwqrhdFCXYCONtxdZZBcTsS03lSqNZpDO8s01PMY87_j5lzWPpgOspkryWOwaEuHnwsrlQfAH8-mMXjO7NC2y8DOVJ55CVEVdwLQzh0qmRtCIvmpYy1t3PfDCBQQgjzazsnjh0Ivmt3h0oBcCq89ggZrU8v2pEwJk-Ijh0xIZdKc6NP69lvVcsZE3> [2] http://matplotlib.org/mpl_toolkits/mplot3d/api.html<http://cp.mcafee.com/d/FZsS86Qm4QnDT4nS3tPqdQPhOCepshhdETjd7aoVBNOVJ6WpEVj7cK8FCQrFCzBcsOUeKr85i5mPVRw2y7NzbOszP-ndAfz6nAV7DYKrQQsEmt8cfZvD4PhPtUtRXBQSnTKhh7ccFFYJteOaqGa8XBgY-F6lK1FJcSCrLOrb5S4TTSkPtPo0dnpH7RCv8xM075lzNmtqDBpjFyGNZpIEpGQK1NJng-iIzVr3Jf8v6oa8yvbCQkmrCzAS2_id41FrlSqNZpDO85Qfc-uqnjh1ecGdNtd42NZpQd41ykOpEwB13RLwxY9Cy2RjWNd426PQSUMrQ0np3acf> 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() |