Bug with setting axis limits

Is the essence of the issue here whether clipping is

    > working properly, in particular, the backend clipping? I
    > would have thought that backend clipping should handle this
    > properly. For which backends does it not? If it doesn't
    > for some, perhaps the issue is to supply our own software
    > clipping; algorithm (possibly much slower though) as an
    > option.

Backend clipping works when the points are on the canvas (the canvas
is the entire figure, not just the axes). Eg, on a 100x100 canvas,
with a line from (0,0) to (100,100) you can clip to the (25,25)
(75,75) rectangle. No problems there.

In Srinath's case, we've asked the backend to plot, for example, a
line from (0,-50000), (0,100) and then clip to the (25,25) (75,75)
rectangle. I don't think the average backend (GTK, Agg) knows what to
do with this line since they expect bitmap/display coords; there are
no backend transformations - everything happens on the front end
(clearly there are pros and cons of this approach, see below).

With data clipping turned, the line class throws out the (0,-50000)
point as illegal.

To fix this in the current framework, we have to identify line
segments in the x,y arrays which intersect the view port but with one
or more end points outside the viewlim, and then draw the appropriate
line through view port. This issue primarily arises for connected
points (line styles '-', '--', and '-.' ). For symbol lines, data
clipping already does the right thing, which is to throw the point
away. However, there are hypothetical wacky cases you can imagine
when you feel like being mean to matplotlib, like a 'o' circle marker
5 million miles from the view limits with a 5 million and one mile
radius..... For connected lines, this could be very costly to
implement since we have to loop over potentially very long arrays; for
markers it would be worse.

Refactoring transforms to the backend would probably fix this
entirely. While non-trivial, this may be the best long term solution,
especially when we want to do things like line and patch collections
for efficient drawing of large numbers of objects. The two major
benefits of the current transform architecture are 1) it lets you
specify locations like 5 points to the left of the right y axes, and
have the transform automatically update in the presence of window
resizes, dpi changes, etc... Very nice when drawing ticks.... and 2)
backends only have to think about one coord system, display, which
makes it easier to implement a backend.

I'm not convinced that it is a terrible thing to have a policy that
matplotlib only plots line segments and markers whose vertices are in
the axes limits, but I'm open to being convinced.

JDH

John Hunter writes:

In Srinath's case, we've asked the backend to plot, for example, a
line from (0,-50000), (0,100) and then clip to the (25,25) (75,75)
rectangle. I don't think the average backend (GTK, Agg) knows what to
do with this line since they expect bitmap/display coords; there are
no backend transformations - everything happens on the front end
(clearly there are pros and cons of this approach, see below).

Hmmm, I've always figured that true clipping works with arbitrary
coordinates, that it does handle exactly the problem that
Srinath reports; when it doesn't then the clipping algorithm
is not really fully implemented. I'm almost certain that OpenGL
handles this correctly and would be surprised if postscript didn't
as well. Is it true that agg will only clip positive coordinates
correctly? If so I'm surprised. Some GUIs may not, but I would
have thought this is standard for any graphics system. On the
other hand, I admit to the possibility of being completely wrong
about this. I'll look up the postscript situation. You are much
more familiar with agg than I am, though (particularly since
agg documentation is not easily accessible).

With data clipping turned, the line class throws out the (0,-50000)
point as illegal.

To fix this in the current framework, we have to identify line
segments in the x,y arrays which intersect the view port but with one
or more end points outside the viewlim, and then draw the appropriate
line through view port. This issue primarily arises for connected

Tell me about it :-). I wrote a Python program to do just this for a
Chaco/kiva/Tk backend. Messy but doable. Clipping polygons is way
messier (many complex algorithms developed for that in the literature).
Performance was ok so long as the original curve didn't
get fragmented into too many segments. (Worst case: 100,000 points;
alternating one point out of range positive and the next out of
range negative).

points (line styles '-', '--', and '-.' ). For symbol lines, data
clipping already does the right thing, which is to throw the point
away. However, there are hypothetical wacky cases you can imagine
when you feel like being mean to matplotlib, like a 'o' circle marker
5 million miles from the view limits with a 5 million and one mile
radius..... For connected lines, this could be very costly to
implement since we have to loop over potentially very long arrays; for
markers it would be worse.

This is a bad case. This is where you do need the polygon clipping
algorithm.

Refactoring transforms to the backend would probably fix this
entirely. While non-trivial, this may be the best long term solution,
especially when we want to do things like line and patch collections
for efficient drawing of large numbers of objects. The two major
benefits of the current transform architecture are 1) it lets you
specify locations like 5 points to the left of the right y axes, and
have the transform automatically update in the presence of window
resizes, dpi changes, etc... Very nice when drawing ticks.... and 2)
backends only have to think about one coord system, display, which
makes it easier to implement a backend.

I'm not sure this is needed if all the important backends (i.e.,
Agg-based, postscript, svg, ...) support this capability. Users
are warned that clipping doesn't work well for the other backends
or the backend calls call clipping functions on their data points
before calling the graphics primitives.

I'm not convinced that it is a terrible thing to have a policy that
matplotlib only plots line segments and markers whose vertices are in
the axes limits, but I'm open to being convinced.

While not common, it does happen. I'm reminded of a handbook that
was produced here that generated an incorrect plot because of
a clipping error. We didn't write that clipping software, but it
was embarrasing nonetheless. It's worth some effort to get it
right I think. Before wasting more discussion over it I guess
I'd like to know which backends don't support generalized clipping
for lines and polygons.

Perry