Skip to content

Speeding up contours with (non-affine) transforms #11464

Closed
@astrofrog

Description

@astrofrog

For the Astropy project, we provide astronomy-specific transforms that users can use in various Matplotlib methods/artists, including e.g. Axes.contour. In fact, we have a sub-class of Axes called WCSAxes which until now just inherited the default contour and contourf. However, the complexity of the transforms means that there is a small overhead (>1-10ms) for every call to the transform that is unrelated to the number of elements to transform.

In Matplotlib, when drawing contours with a transform:

ax.contour(..., transform=...)

each individual path in the contour is passed to transform_path_non_affine. This is done here:

https://github.com/matplotlib/matplotlib/blob/master/lib/matplotlib/collections.py#L191

However, this means that in cases where a contour map has say 1000 individual lines (not that uncommon with some astronomy images), drawing a contour map can take >10s.

I found a solution in astropy/astropy#7568 - override contour and call matplotlib's contour without the transform, then modify the vertices in-place afterwards by constructing a single array with all the vertices and transforming it in one go and splitting it up again. The key function is:

https://github.com/astropy/astropy/pull/7568/files#diff-421f6873fdd2d8a90f39f3050534b0c3R139

This dramatically sped up drawing contours in our case. The reason I'm opening this issue (as suggested by @dopplershift on Gitter) is that this solution is not specific to Astropy. In fact, this could be copied almost as-is into Matplotlib if there was interest. In our case, there is basically no downside to doing this performance-wise even when there are very few contour lines, and I think this is generally true for this approach.

Feel free to close this if you'd rather not port this over to Matplotlib though, as there may be subtleties I am not aware of!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions