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 <mal...@ryerson.ca> 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, rows-1, rstride):
>
>             for cs in np.arange(0, cols-1, 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(cols-1, cs+cstride)][rs:min(rows,
> rs+rstride+1)]
>
>                     zbase = a[min(rows-1, 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:mal...@ryerson.ca]
> Sent: November-25-09 8:42 PM
> To: matplotlib-users@lists.sourceforge.net
> Subject: Re: [Matplotlib-users] 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
> open-source 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\site-packages\mpl-toolkits\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
> re-complied 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, rows-1, rstride):
>
>             for cs in np.arange(0, cols-1, 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(cols-1, cs+cstride)][rs:min(rows,
> rs+rstride+1)]
>
>                     zbase = a[min(rows-1, 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.al...@ngcaerospace.com]
> Sent: November-23-09 3:42 PM
> To: matplotlib-users@lists.sourceforge.net
> Subject: [Matplotlib-users] 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
>
> mal...@ryerson.ca
>
>
>
> ------------------------------------------------------------------------------
> Join us December 9, 2009 for the Red Hat Virtual Experience,
> a free event focused on virtualization and cloud computing.
> Attend in-depth sessions from your desk. Your couch. Anywhere.
> http://p.sf.net/sfu/redhat-sfdev2dev
> _______________________________________________
> Matplotlib-users mailing list
> Matplotlib-users@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/matplotlib-users
>
>



-- 
Reinier Heeres
Tel: +31 6 10852639
------------------------------------------------------------------------------
Return on Information:
Google Enterprise Search pays you back
Get the facts.
http://p.sf.net/sfu/google-dev2dev
_______________________________________________
Matplotlib-users mailing list
Matplotlib-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-users

Reply via email to