Skip to content

[feature request] circle -> SVG <circle> #17424

Open

Description

@nschloe

When saving a scene as SVG, circles are translated to <path> elements. For example

import matplotlib.pyplot as plt

circ = plt.Circle((0.0, 0.0), 1.0, alpha=0.5)
plt.gca().add_patch(circ)
plt.autoscale()

plt.gca().set_aspect("equal")
plt.gca().set_axis_off()
# plt.show()
plt.savefig("out.svg")
   <g id="patch_2">
    <path clip-path="url(#p50a8cc0149)" d="M 236.16 295.488.
C 268.238967 295.488 299.008381 282.742891 321.691636 260.059636.
C 344.374891 237.376381 357.12 206.606967 357.12 174.528.
C 357.12 142.449033 344.374891 111.679619 321.691636 88.996364.
C 299.008381 66.313109 268.238967 53.568 236.16 53.568.
C 204.081033 53.568 173.311619 66.313109 150.628364 88.996364.
C 127.945109 111.679619 115.2 142.449033 115.2 174.528.
C 115.2 206.606967 127.945109 237.376381 150.628364 260.059636.
C 173.311619 282.742891 204.081033 295.488 236.16 295.488.
z
" style="fill:#1f77b4;opacity:0.5;"/>
   </g>

A better suited approach would be SVG's own <circle> element:

    <circle cx="236" cy="174.5" r="121" fill="red" />

Activity

  1. tacaswell commented on May 15, 2020

    @tacaswell
    Member

    How would you go about implementing this?

    I am not sure we want to add more (optional) methods to the renderer and I am also not sure that we want to try to look at a path and infer back that this used to be a circle.

    On the other hand we do have a precedent for this in the collections API on the renderers.

  2. anntzer commented on May 15, 2020

    @anntzer
    Contributor

    This is something I've been thinking about (in particular wrt #14852). I think this would be 1) great and 2) really tricky to implement in a solid manner.

    More generally, I think we should add a new Path code, "arc", which draws, well, arcs. This is because most (all(?)) renderers actually have a way to represent arcs (SVG arc, cairo_arc(), etc.), so that one can just insert e.g.

    ARC x0 y0
    ARC x1 y1
    ARC x2 y2
    

    etc. with enough points to unambiguously represent the arc, and let the renderer handle that as needed. The problem is that we more or less need to be able to only put "real" points for xy coordinates, because a lot of code out there assumes that you can apply an affine transform (let's not worry about nonlinear ones because that case is not well defined, but affine transforms are everywhere) by just working on each point individually, and for performance reasons we probably want to keep that. So basically we need a representation that uses only "real" xy points and that makes sense under affine transform. In particular that excludes storing e.g. radii, angles, etc. On the other hand, this means that support for arbitrarily oriented elliptical arcs also comes together with it.
    I think the representation more or less needs to be something like:

    (xstart ystart): start of the arc
    (xc yc): center of the arc
    (x' y'): auxiliary point
    (xstop ystop): stop of the arc
    

    where x' y' is somewhere in the arc from start to stop (so that we know whether to draw the clockwise part or the counterclockwise part) -- note that this representation is (I think) stable under affine transforms. Probably it would be good to also derive once and for all the math for converting back and forth between this representation and more "standard" ones.

  3. tacaswell commented on May 15, 2020

    @tacaswell
    Member

    To start getting arbitrary ellipses you could just keep adding auxiliary points until you pin down all of the degrees of freedom. If we are going to go down this route might as well add a family of ArcN codes.

    Working out that math does sound fun :)

  4. anntzer commented on May 15, 2020

    @anntzer
    Contributor

    The point is that you don't need so many points, I think start-center-mid-stop is enough. It's just the math...

  5. brunobeltran commented on May 15, 2020

    @brunobeltran
    Contributor

    Just wanted to chime in that if this does happen, I have all of my path length, center of mass, area stuff computed for arcs as well (since I assumed matplotlib would have them before I even started coding).

    Happy to TeX it up nice and pretty if someone gets around to this :)

    (does sound like fun...)

  6. tacaswell commented on May 16, 2020

    @tacaswell
    Member

    @brunobeltran have at it!

    I think putting all of the path stuff in the docs would be good as well.

  7. anntzer commented on Jun 2, 2020

    @anntzer
    Contributor

    As a side point, true circles would also make Arc (#17547) unnecessary (or much simpler).

  8. github-actions commented on Aug 2, 2023

    @github-actions

    This issue has been marked "inactive" because it has been 365 days since the last comment. If this issue is still present in recent Matplotlib releases, or the feature request is still wanted, please leave a comment and this label will be removed. If there are no updates in another 30 days, this issue will be automatically closed, but you are free to re-open or create a new issue if needed. We value issue reports, and this procedure is meant to help us resurface and prioritize issues that have not been addressed yet, not make them disappear. Thanks for your help!

  9. h-vetinari commented on Aug 2, 2023

    @h-vetinari

    Still relevant

  10. added
    keepItems to be ignored by the “Stale” Github Action
    and removed
    status: inactiveMarked by the “Stale” Github Action
    on Aug 2, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Difficulty: Hardhttps://matplotlib.org/devdocs/devel/contribute.html#good-first-issuesNew featurekeepItems to be ignored by the “Stale” Github Actiontopic: path handling

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions