From: Andrew S. <str...@as...> - 2004-03-16 07:44:42
Attachments:
fill_patch.txt.gz
|
G'day! I've implemented a mostly-matlab-compatible "fill" command. I attach it for your pleasure and hopeful inclusion into matplotlib. (This is an extension of our previous email discussion and involved me going and using matlab for a bit to get a feel for their API.) 2 points: 1) Is there any reason why the Patch class doesn't have get_xdata() and get_ydata() methods? 1b) If not, can we add them and let Axes.add_patch(patch) call "self.xaxis.datalim.update(patch.get_xdata())" ? 2) I think there's still a Polygon facecolor bug. John, I thought you fixed the Polygon facecolor bug -- my patches.py code matches the bugfix you emailed the list, but I still don't get the facecolor with the PS, GTK or Agg backends. Cheers! Andrew |
From: John H. <jdh...@ac...> - 2004-03-16 12:44:55
|
>>>>> "Andrew" == Andrew Straw <str...@as...> writes: Andrew> 2 points: Andrew> 1) Is there any reason why the Patch class doesn't have Andrew> get_xdata() and get_ydata() methods? 1b) If not, can we Andrew> add them and let Axes.add_patch(patch) call Andrew> "self.xaxis.datalim.update(patch.get_xdata())" ? I removed this one day when I was trying to improve the painfully slow pcolor code. The way patches were getting their xlimits was slow. After spending some time with the profiler, I opted to set the axes limits manually for scatter and pcolor rather than pay the additional performance hit in add_patch. This makes the code a little more difficult to maintain. Perhaps better than get_xdata is get_xlim. What is the natural xdata for a circle characterized by a center and radius? xlim is clear. I added this for Polygon and modified the fill command to use it, and will add it to the other patch commands and use it in add_patch in due time. Or feel free to take the lead :-) Andrew> 2) I think there's still a Polygon facecolor bug. John, I Andrew> thought you fixed the Polygon facecolor bug -- my Andrew> patches.py code matches the bugfix you emailed the list, Andrew> but I still don't get the facecolor with the PS, GTK or Andrew> Agg backends. The problem was that you didn't set fill=True in the Polygon constructor. I added this and it works great. Here is my fill_demo code - if you have something more impressive for the examples dir send it along. from matplotlib.matlab import * t = arange(0.0, 1.01, 0.01) s = sin(2*2*pi*t) fill(t, s*exp(-5*t), 'r') grid(True) show() Changes are in CVS. Thanks! JDH |
From: Andrew S. <str...@as...> - 2004-03-17 10:49:10
|
On Tuesday, March 16, 2004, at 10:52 PM, John Hunter wrote: > > Changes are in CVS. Great! (Too bad SF's CVS servers are way behind for anonymous checkouts--it's driving me nuts! I had to piece together a recent CVS checkout by downloading the CVSROOT tarball...) Now, my question is, can we set edgecolor=None on a patch and have it not draw the edges of the patch? Or whatever is the most matlab-compatible way, assuming one can do this in matlab. Or, perhaps by analogy to fill=True we could have stroke=True as well. Perhaps this is already "in there"--if so, what do I do? Keep up the great work! Andrew |
From: John H. <jdh...@ac...> - 2004-03-17 21:17:27
|
>>>>> "Andrew" == Andrew Straw <str...@as...> writes: Andrew> Now, my question is, can we set edgecolor=None on a patch Andrew> and have it not draw the edges of the patch? Or whatever Andrew> is the most matlab-compatible way, assuming one can do Andrew> this in matlab. Or, perhaps by analogy to fill=True we Andrew> could have stroke=True as well. Perhaps this is already Andrew> "in there"--if so, what do I do? Unfortunately, the backend design doesn't accomodate this so nicely. The workaround is to set the edge and the face color to be the same. You pay a performance hit but otherwise *it works*. To do it right will require, but will require some extra work. A typical signature is: def draw_rectangle(self, gcEdge, rgbFace, x, y, width, height): The gc contains extra information in addition to color that the backend may optionally use in drawing the polygon: alpha, line thickness, dash style. This is why facecolor and edgecolor are set differently in the current framework. I'm not sure what the cleanest design is to overcome this; it would definitely require changing all the draw patch methods of all the backends. Setting gcEdge to None is probably the easiest but you would lose alpha information in doing so that we may want to use in drawing filled polygons/rectangles. An alternative is to simply remove the gc and explicitly pass the required properties. This brings up my next big matplotlib project - handling large quantities of polygon data efficiently. I would like to define all the properties that are required for polygon drawing so that we can provide optional backend methods like draw_rectangles and draw_ellipses which could be implemented more efficiently than the current methods. I've always found the gcEdge and rgbFace a bit hackish for polygons and wanted to clean this up at least for the polygon collection code. So what is needed to fully specify a 2D polygon? * vertices * edge thickness * edge dashes, eg a dashed rectangle surrounding a region * edge color: rgb or none for invisible * face color: rgb or none for invisible * alpha Anything else? I was thinking about a signature along the lines of # good for drawing a polygon map of a country draw_polygons(N, verts, widths, dashes, edges, faces, alphas, trans): Any of these args can be an N length sequence or a 1 length sequence. If the sequence is length one, the backend just uses the 0th index for all the polygons. verts: a list like [p1, p2, p3] where p1 = ( (x1,y1), (x2,y2), ...) and so on widths: the edge thickness dashes: a list like [d1,d2,d3] where d1 = ( inkon1, inkoff1, inkoff1, inkoff2). This may be overkill; in 99.9999% of the cases as single dash style is all anyone will want. Perhaps best to do away with dashes altogether for polygon collections. edges : a list of [rgb1, rgb2, ...] faces : a list of [rgb1, rgb2, ...] alphas: a list of [alpha1, alpha2, ...] trans: a six-tuple, postscript/agg style transformation vector. The last arg violates the current design in which backends don't have to worry about transformations. But doing the transformations of verts in python incurs a performance penalty that obviates the purpose of the function so it seems worth it. draw_polygons really isn't ideally suited to a scatter or pcolor though. In those cases you would spend a lot of time in python constructing your polygons vertices when you really only need one shape placed at a many locations, possibly scaled. # good for drawing a polygon map of a country draw_identical(N, path, offsets, scales, widths, dashes, edges, faces, alphas, trans): path : is a sequence of rlineto's defining the shape of the polygon offsets : a sequence of [(x1,y1), (x2,y2), ...] for the path scales : a sequence of scales for each path; [scale1, scale2, scale3, ...] or [ (sx1, sy2), (sx2, sy2), ...] allowing the x and y directions to scale independently other args are the same This seems a bit cumbersome. I'm trying to think of the fewest functions that will handle at least * pcolor with rectangles * scatters with markers of arbitrary shape and possibly varying sizes * maps, eg, map of voting by county in the US. Thoughts? JDH |