I have a working draft of

something that may work for this problem on the transforms branch.

I am happy to backport this to the trunk, but that will require some

effort, as the implementation relies on many of the new geometric

utilities on the branch that would also have to be brought over. It

may be some time until the branch is ready for production use, but if you

are able to use it to experiment with this approach to this specific

problem, that would certainly make my life easier, so I don’t have to do

the backporting work more than once.

Attached is a plot comparing the new approach (above) vs. a 750-edge

polygonal approximation for the ellipses (based directly on James Evans’

example). Here’s a description of what it does:

```
Ellipses are normally drawn
```

using an approximation that uses

```
eight cubic bezier
```

splines. The error of this approximation

```
is 1.89818e-6, according to
```

this unverified source:

```
Lancaster,
```

Don. Approximating a Circle or an Ellipse Using

```
Four Bezier Cubic
```

Splines.

http://www.tinaja.com/glib/ellipse4.pdf

```
There is a use case where very
```

large ellipses must be drawn

```
with very high accuracy, and
```

it is too expensive to render the

```
entire ellipse with enough
```

segments (either splines or line

```
segments). Therefore, in
```

the case where either radius of the

```
ellipse is large enough that
```

the error of the spline

```
approximation will be visible
```

(greater than one pixel offset

```
from the ideal), a different
```

technique is used.

```
In that case, only the visible
```

parts of the ellipse are drawn,

```
with each visible arc using a
```

fixed number of spline segments

```
(8). The algorithm
```

proceeds as follows:

```
1. The points
```

where the ellipse intersects the axes bounding

```
box are
```

located. (This is done be performing an inverse

```
transformation on
```

the axes bbox such that it is relative to

```
the unit circle --
```

this makes the intersection calculation

```
much easier than
```

doing rotated ellipse intersection

```
directly).
This uses the
```

“line intersecting a circle” algorithm from:

```
Vince,
```

John. Geometry for Computer Graphics: Formulae,

Examples & Proofs. London: Springer-Verlag, 2005.

```
2. The angles of
```

each of the intersection points are

```
calculated.
3. Proceeding
```

counterclockwise starting in the positive

```
x-direction, each
```

of the visible arc-segments between the

```
pairs of vertices
```

are drawn using the bezier arc

```
approximation
```

technique implemented in Path.arc().

Cheers,

Mike

Ted Drain wrote:

All of these sound like good

ideas to me. Just for some history: the original reason we worked

w/ John to get an Ellipse primitive in (vs a normal line plot of sampled

points) were to:

Ted

John Hunter wrote:

I don’t know if the current MPL

architecture can support this but it

would be nice if it worked that way. We have people making

decisions

based on what these plots show that affect spacecraft worth hundreds

of millions of dollars so it’s important that we’re plotting

things accurately.

We can support this, but I think

we would do this with an arc class

rather than an ellipse class, and write a special case class that is

viewlim aware.

I agree – I think there are two uses cases

for ellipse that are in

conflict here. One is these large ellipses, the other is for

things

like scatter plots, where speed and file size is more important than

accuracy. My mind was probably stuck on the latter as I’ve worked

along

the transforms branch.

A simple example of a line that

has analogous

behavior is examples/clippedline.py, which clips the points outside

the viewport and draws in a different style according to the

resolution of the viewlim. The reason I think it would be

preferable

to use an arc here is because we won’t have to worry about filling

the

thing when we only approximate a section of it. You could feed in

a

360 degree elliptical arc and then zoom into a portion of it.

With the 8 point ellipse as is, and the addition of an arc class

that

does 4 or 8 point approximation within the zoom limits, should that

serve your requirements?

As a possible starting point, the

transforms branch already has

arc-approximation-by-cubic-bezier-spline code. It determines the

number

of splines to use based on the radians included in the arc, which is

clearly not what we want here. But it should be reasonably

straightforward to make that some fixed number and draw the arc

between

the edges of the axes. Or, alternatively, (and maybe this is what

John

is suggesting), the arc could be approximated by line segments (with

the

number of segments something like the number of pixels across the

axes).

To my naive mind, that seems more verifiable – or at least it

puts

the responsibility of getting this right all in one place.

IMHO, these spline approximation tricks are all just with the aim of

pushing curve rendering deeper into the backends for speed and file

size

improvements. But obviously there needs to be a way around it when

it

matters.

Cheers,

Mike

–

Michael Droettboom

Science Software Branch

Operations and Engineering Division

Space Telescope Science Institute

Operated by AURA for NASA

SF.Net email is sponsored by:

Check out the new SourceForge.net Marketplace.

It’s the best place to buy or sell services for

just about anything Open Source.

http://sourceforge.net/services/buy/index.php

Matplotlib-devel mailing list

Matplotlib-devel@lists.sourceforge.net

https://lists.sourceforge.net/lists/listinfo/matplotlib-devel

Ted Drain Jet Propulsion Laboratory

ted.drain@…179…

SF.Net email is sponsored by: Check out the new SourceForge.net

Marketplace.

It’s the best place to buy or sell services for

just about anything Open Source.

http://sourceforge.net/services/buy/index.php

Matplotlib-devel mailing list

Matplotlib-devel@lists.sourceforge.net

https://lists.sourceforge.net/lists/listinfo/matplotlib-devel

SF.Net email is sponsored by: Check out the new SourceForge.net

Marketplace.

It’s the best place to buy or sell services for

just about anything Open Source.

http://sourceforge.net/services/buy/index.php

Matplotlib-devel mailing list

Matplotlib-devel@lists.sourceforge.net

https://lists.sourceforge.net/lists/listinfo/matplotlib-devel