|
From: Reinier H. <re...@he...> - 2009-12-10 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 <ma...@ry...> 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:ma...@ry...]
> Sent: November-25-09 8:42 PM
> To: mat...@li...
> 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:mik...@ng...]
> Sent: November-23-09 3:42 PM
> To: mat...@li...
> 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
>
> ma...@ry...
>
>
>
> ------------------------------------------------------------------------------
> 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
> Mat...@li...
> https://lists.sourceforge.net/lists/listinfo/matplotlib-users
>
>
--
Reinier Heeres
Tel: +31 6 10852639
|