|
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
|