From: Holger Brandsmeier <holger.brandsmeier@sa...>  20110930 16:49:14

> That is why you have to work with the 3D objects from > mpl_toolkits.mplot3d.art3d directly. There isn't a lot of documentation, so > your best bet is to look at the source code of the module. Indeed, I was able to extract the necessary pieces from the source code. In fact I split the function `plot_surface` into two functions `polyMeshFromMeshGrid` and `plot_surfaceMesh`. The first functions takes the meshgrid arguments and produces a list of polygons that should be drawn, the second functions finally displays them (the code in plot_surface is already structured like this). With this approach I can plot functions which are made up of several parts which each have meshgrid structure. Also I can add raw polygons to the mesh. Maybe this splitting makes sense in the online code as well? Holger def polyMeshFromMeshGrid(self, X, Y, Z, *args, **kwargs): rows, cols = Z.shape tX, tY, tZ = np.transpose(X), np.transpose(Y), np.transpose(Z) rstride = kwargs.pop('rstride', 10) cstride = kwargs.pop('cstride', 10) if 'facecolors' in kwargs: fcolors = kwargs.pop('facecolors') else: color = np.array(colorConverter.to_rgba(kwargs.pop('color', 'b'))) fcolors = None cmap = kwargs.get('cmap', None) norm = kwargs.pop('norm', None) vmin = kwargs.pop('vmin', None) vmax = kwargs.pop('vmax', None) shade = kwargs.pop('shade', cmap is None) lightsource = kwargs.pop('lightsource', None) # Shade the data if shade and cmap is not None and fcolors is not None: fcolors = self._shade_colors_lightsource(Z, cmap, lightsource) polys = kwargs.pop('polys', []) normals = kwargs.pop('normals', []) #colset contains the data for coloring: either average z or the facecolor colset = kwargs.pop('colset', []) for rs in np.arange(0, rows1, rstride): for cs in np.arange(0, cols1, cstride): ps = [] corners = [] for a, ta in [(X, tX), (Y, tY), (Z, tZ)]: ztop = a[rs][cs:min(cols, cs+cstride+1)] zleft = ta[min(cols1, cs+cstride)][rs:min(rows, rs+rstride+1)] zbase = a[min(rows1, rs+rstride)][cs:min(cols, cs+cstride+1):] zbase = zbase[::1] zright = ta[cs][rs:min(rows, rs+rstride+1):] zright = zright[::1] corners.append([ztop[0], ztop[1], zbase[0], zbase[1]]) z = np.concatenate((ztop, zleft, zbase, zright)) ps.append(z) # The construction leaves the array with duplicate points, which # are removed here. ps = zip(*ps) lastp = np.array([]) ps2 = [] avgzsum = 0.0 for p in ps: if p != lastp: ps2.append(p) lastp = p avgzsum += p[2] polys.append(ps2) if fcolors is not None: colset.append(fcolors[rs][cs]) else: colset.append(avgzsum / len(ps2)) # Only need vectors to shade if no cmap if cmap is None and shade: v1 = np.array(ps2[0])  np.array(ps2[1]) v2 = np.array(ps2[2])  np.array(ps2[0]) normals.append(np.cross(v1, v2)) return polys, normals, colset def plot_surfaceMesh(self, polys, normals, colset, *args, **kwargs): had_data = self.has_data() rows, cols = Z.shape rstride = kwargs.pop('rstride', 10) cstride = kwargs.pop('cstride', 10) if 'facecolors' in kwargs: fcolors = kwargs.pop('facecolors') else: color = np.array(colorConverter.to_rgba(kwargs.pop('color', 'b'))) fcolors = None cmap = kwargs.get('cmap', None) norm = kwargs.pop('norm', None) vmin = kwargs.pop('vmin', None) vmax = kwargs.pop('vmax', None) linewidth = kwargs.get('linewidth', None) shade = kwargs.pop('shade', cmap is None) lightsource = kwargs.pop('lightsource', None) polyc = art3d.Poly3DCollection(polys, *args, **kwargs) if fcolors is not None: if shade: colset = self._shade_colors(colset, normals) polyc.set_facecolors(colset) polyc.set_edgecolors(colset) elif cmap: colset = np.array(colset) polyc.set_array(colset) if vmin is not None or vmax is not None: polyc.set_clim(vmin, vmax) if norm is not None: polyc.set_norm(norm) else: if shade: colset = self._shade_colors(color, normals) else: colset = color polyc.set_facecolors(colset) self.add_collection(polyc) x, y, z = [], [], []; for pol in polys: for p in pol: x.append(p[0]) y.append(p[1]) z.append(p[2]) self.auto_scale_xyz(x, y, z, had_data) return polyc 