From: Reinier Heeres <reinier@he...>  20091210 00:44:42

Hi Mike, Sorry for the slow reply, but I put support for this in the development version in SVN. It can also do a bit of shading to make the surface look more structured. Note that the fact that a 40x40 grid turns into 39x39 squares is expected behavior: the code assumes the 40 points are the *edges* of the patches. There are only 39 patches between 40 points. Regards, Reinier On Tue, Dec 1, 2009 at 3:06 AM, Mike Alger <malger@...> wrote: > After a weekend of no replies I managed to figure a way out myself > > As this was “left to the reader as an exercise” I will leave the integration > or improvement of this solution as an exercise to the next reader > > What I have done is basically cloned the plot surface function and replaced > the avgz variable with a reference to the “colors” parameter i have added to > the function call. > > This code doesn’t center things perfectly with respect to the grid (for > some reason a 40x40 grid turns into 39x39 grid in the function) again this > is something else that could be improved, however I am happy with it and a > one pixel shift won’t be missed in my plots. I also have no real clue as to > what the following comments was about > > > > # The construction leaves the array with duplicate points, > which > > # are removed here. > > > > but it is probably related to my non centered plots. > > > > > > > > > > What follows is the modified function : > > > > > > > > def plot_surface2(self, X, Y, Z, colors, *args, **kwargs): > > ''' > > Create a surface plot. > > > > By default it will be colored in shades of a solid color, > > but it also supports color mapping by supplying the *cmap* > > argument. > > > > ========== ================================================ > > Argument Description > > ========== ================================================ > > *X*, *Y*, Data values as numpy.arrays > > *Z* > > *colors* an array the same size as z that contains a separate > color data > > *rstride* Array row stride (step size) > > *cstride* Array column stride (step size) > > *color* Color of the surface patches > > *cmap* A colormap for the surface patches. > > ========== ================================================ > > ''' > > > > had_data = self.has_data() > > > > 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) > > > > color = kwargs.pop('color', 'b') > > color = np.array(colorConverter.to_rgba(color)) > > cmap = kwargs.get('cmap', None) > > > > polys = [] > > normals = [] > > avgz = [] > > 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) > > ################################## > > Begin of changes > > ################################## > > #avgz.append(avgzsum / len(ps2)) > > avgz.append(colors[rs][cs]) > > ################################## > > end of changes > > ################################## > > > > v1 = np.array(ps2[0])  np.array(ps2[1]) > > v2 = np.array(ps2[2])  np.array(ps2[0]) > > normals.append(np.cross(v1, v2)) > > > > polyc = art3d.Poly3DCollection(polys, *args, **kwargs) > > if cmap is not None: > > # polyc.set_array(np.array(colors)) > > polyc.set_array(np.array(avgz)) > > polyc.set_linewidth(0) > > else: > > colors = self._shade_colors(color, normals) > > polyc.set_facecolors(colors) > > > > self.add_collection(polyc) > > self.auto_scale_xyz(X, Y, Z, had_data) > > > > return polyc > > > > > > From: Mike Alger [mailto:malger@...] > Sent: November2509 8:42 PM > To: matplotlibusers@... > Subject: Re: [Matplotlibusers] Color in 3d plots > > > > I have been looking at this for the past day and in am pretty sure I could > replace the instance of polyc by the “cmap if statements” my colour array > and I should be able to get close to what I want. However I am new to both > python & mpl, and I am not entirely sure in how I would go about testing my > hypothesis. Furthermore I am also relatively new to submitting fixes to > opensource projects so I have lots of questions about how I would go about > suggesting a modification. > > > > 1.) can I just modify the file in the > C:\python26\Lib\sitepackages\mpltoolkits\mplot3d\axes3d.py file to do my > tests? > > a. Also, where are these files usually kept in a linux environment ? > > b. What do I do with the. pyc files with the same name? are they > recomplied automatically when I call the function externally? > > 2.) Is this capability already built in with the colour argument ? if so > how do I properly call it? > > 3.) If I do make a modification should it be as a separate function with > the additional variable or should I try to stuff the new capability into the > old function > > 4.) is there a clean easy to follow tutorial for submitting changes via > svn or can I rely on someone else to do the final commit? > > > > I have attached the function in question for reference to save others from > digging down into their python directories > > > > > > Again thanks for taking your time to help me figure this out > > > > Mike Alger > > > > < Code> > > def plot_surface(self, X, Y, Z, *args, **kwargs): > > ''' > > Create a surface plot. > > > > By default it will be colored in shades of a solid color, > > but it also supports color mapping by supplying the *cmap* > > argument. > > > > ========== ================================================ > > Argument Description > > ========== ================================================ > > *X*, *Y*, Data values as numpy.arrays > > *Z* > > *rstride* Array row stride (step size) > > *cstride* Array column stride (step size) > > *color* Color of the surface patches > > *cmap* A colormap for the surface patches. > > ========== ================================================ > > ''' > > > > had_data = self.has_data() > > > > 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) > > > > color = kwargs.pop('color', 'b') > > color = np.array(colorConverter.to_rgba(color)) > > cmap = kwargs.get('cmap', None) > > > > polys = [] > > normals = [] > > avgz = [] > > 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) > > avgz.append(avgzsum / len(ps2)) > > > > v1 = np.array(ps2[0])  np.array(ps2[1]) > > v2 = np.array(ps2[2])  np.array(ps2[0]) > > normals.append(np.cross(v1, v2)) > > > > polyc = art3d.Poly3DCollection(polys, *args, **kwargs) ## this is > where a modification could be made to allow for a separate colour matrix > > if cmap is not None: > > polyc.set_array(np.array(avgz)) > > polyc.set_linewidth(0) > > else: > > colors = self._shade_colors(color, normals) > > polyc.set_facecolors(colors) > > > > self.add_collection(polyc) > > self.auto_scale_xyz(X, Y, Z, had_data) > > > > return polyc > > </Code> > > > > From: Mike Alger [mailto:mike.alger@...] > Sent: November2309 3:42 PM > To: matplotlibusers@... > Subject: [Matplotlibusers] Color in 3d plots > > > > This may be a dumb question, however I have been scratching my head trying > to figure out how to plot a 3 dimensional plot with with a colour map > different from the elevation(Z) parameter. > > > > An example of this done in Matlab would be > > > > [X,Y,Z] = peaks(30); > > C=Z'% could be anything other than Z as long as it has the same dimensions > > surf(X,Y,Z,C) > > > > axis([3 3 3 3 10 5]) > > > > > > Is this possible with matplotlib '0.99.1' > > > > If so how do i go about doing this is there some sample code? > > > > Mike Alger, M.A.Sc > > malger@... > > > >  > Join us December 9, 2009 for the Red Hat Virtual Experience, > a free event focused on virtualization and cloud computing. > Attend indepth sessions from your desk. Your couch. Anywhere. > http://p.sf.net/sfu/redhatsfdev2dev > _______________________________________________ > Matplotlibusers mailing list > Matplotlibusers@... > https://lists.sourceforge.net/lists/listinfo/matplotlibusers > >  Reinier Heeres Tel: +31 6 10852639 