I wonder if you cached some of the interval tests whether you might
see some additional speedups. Eg, something like
....
You could do this, but I don't think you would even notice the difference.
Really, my impression is that the only things that really take time are
drawing a line, and maybe doing excessive amounts of
multiplication/division. It can't hurt to try, though, if there is time.
The full rectangle test would give a boost in some cases, but I think
these cases are going to be extremely rare, so I didn't bother. All x vs
time type data works fine under the simpler test, for example. I'll give
it a try sometime later this week though, just to see.
There is one case where your culling algorithm will fail, I think
view window x2
···
On Mon, July 9, 2007 10:57 am, John Hunter wrote:
-----------------------------
> >
> >
> >
_______________
x1
It doesn't fail, as you can see by trying to plot something like that.
Both points need to be on the 'undrawn' side of one of the lines of the
box. In your case, the points are to either side of the top line, the left
line and the bottom line, and are both to the 'drawn' side of the right
line. They are not both on the undrawn side of any line.
Do you think it is worth making this a line property so users can
tweak it? There are a couple of ways to get the line property information
into the backend -- the typical way is to make a corresponding graphics
context property and then set it in the line draw method.
I thought of doing this, but I didn't get to it. I originally wrote it
just for myself. If you know how, it seems like a good idea.
I do think it would be nice to support culling points outside the
viewport across backends. A recurring criticism is that our postscript
files with lots of points, in which the zoom is set to just a subset of
points, are quite large because we use graphics clipping to get rid of
them but the data are still in the file. As you note, this can be a good
thing for users who want to do post-hoc editing, and culling is tricky
because, for example, a point whose center is outside the viewport could
have a edge vertex inside the viewport. So we would need polygon
intersections to do it right (and even this would not completely solve the
case of polygons with thick edge strokes) but having the option to cull
points whose centers fell outside the viewport, or line segments whose
vertices fell outside the x and y intervals, would be a big win in most
common use cases.
Dropping parallel lines in the visible area still seems like a bad idea
for SVG, but I can see that culling points outside it could be OK. There
are two things you want to cull: lines between two points, and polygons
drawn around single points.
I don't know exactly how the polygon parts work in matplotlib, but it
seems reasonable that you could find an upper value to the radius of the
polygon around a point. Add max radius of polygon + stroke width to get a
'bound' value, and then instead of (x < 0 || x > width ...) do (x < -bound
x > width + bound ...) to cull. Just make the bound big enough that you
are sure nothing could be in the viewing area, even if you draw a few more
points than you need to.
For lines between two points, if you use just the simple cull test I am
using, you could do the same thing as for polygons where the bound depends
only on the stroke width. Actually, I should really do that in the agg
code. If you use a full box test, you would again need a more complicated
algorithm with extra intersection tests, it could get messy.
Also, I am not sure how and when transforms are applied to the data, but I
can imagine the transform and culling interfering with each other. In the
agg code, the data is transformed to its final pixel units before I do
culling.
Allan