Skip to content

Figure.set_size_cm and Figure(figsize_cm=) as an alternative to figsize/set_size_inches #12402

Closed as not planned

Description

@wavexx

I grew tired of having to convert my units just for the sake of specifying the figure size. I'd like to specify the figure size directly in a metric unit, nominally centimeters (or millimeters, no difference). In most EU countries metric is the norm. I only have to deal with inches when looking at monitor sizes, printing, and matplotlib :(

I've found at least two issues about this: #1369 and the more generic #9226.

Of course, having support for generic unit specifiers would be nice, but I'm not entirely satisfied by the extra complexity of #9226. I'm also thorn about (size, unit) tuples, because I don't ever think I'm going to specify the figure size in AU, or picometers. Cm is regularly used for anything that fits paper.

I see two cases where inches are specified in the rc:

  • figure.figsize
  • savefig.pad_inches

In the api, there is the figsize kwarg, I guess a pad_inches kwarg, and the set_size_inches method.

What abound the KISS approach: add a figsize_cm kwarg, pad_cm, and the set_size_cm method, and the two respective rcParams? Fully backward compatible, and allows metric countries to get by easily.

I could easily contribute such a patch.

Activity

  1. jklymak commented on Oct 4, 2018

    @jklymak
    Member

    pads and margins are often specified in points and ems, as well as cms and ins, so the motivation for something more general was not AU or picometers.

  2. wavexx commented on Oct 4, 2018

    @wavexx
    ContributorAuthor

    It's a fair point, and I agree that generalizing the units in the various points would be nice. There are many places where I feel the required units are basically arbitrary. Like in annotations, you can choose between 'offset points' or 'offset pixels'. I often eyeball numbers because I cannot use consistent unit throughout.

    I just fear such a task will require a lot of changes to be done, and done well, taking considerable time. And while we wait, I still need to chug down inches just to set the figure size.

  3. jklymak commented on Oct 4, 2018

    @jklymak
    Member

    I'm -1 on a new kwarg.

    I personally think we should allow figsize=(5, 6) and figsize=('10cm', '12cm') So strings are parsed as having units, non-strings are the default inches. We could start with just doing this w/ figsize kwarg and see if expands. Others are against a string parser, but I disagree - its the simplest and doesnt' require someone importing another library.

  4. added this to the v3.1 milestone on Oct 4, 2018
  5. wavexx commented on Oct 4, 2018

    @wavexx
    ContributorAuthor

    I would be ok with that. A string parser is not great, but not any worse than what we do we colors.
    In this case, for set_size_inches, I'd add a set_size() that works in the way you describe. Similarly for kwargs that say "inches". Using set_size_inches('2mm', '2mm') would be weird/bad.

  6. jklymak commented on Oct 4, 2018

    @jklymak
    Member

    That sounds reasonable to me. But I'd give the folks who didnt like the idea of a string parser a day or so to register their concerns before I spent a lot of time making a PR ;-)

  7. ImportanceOfBeingErnest commented on Oct 5, 2018

    @ImportanceOfBeingErnest
    Member

    You would indeed save two characters of typing.

    figsize=("8cm","8cm")####|
    figsize=(8/2.54,8/2.54)##|
    

    It is of course an advantage not having to remember the number 2.54.
    I wouldn't complete oppose the option to use other units, but I think it'll somehow need to be consistent. If you specified the figure size in centimeters, will fig.get_figwidth return inches? Or centimeters? If there was a fig.get_figwidth_cm would it return a number, or a string?
    Would the dpi also get its centimeter-equivalent dpcm? Or would there be a fig.dpcm_scale_trans transform?

    Essentially instead of the number 2.54 the user will then need to remember which methods exist for centimeters and which don't and possibly their return type. As soon as the "5cm" is introduced, where do you stop, i.e. would plt.bar(x,y, width="0.5cm") ok? But then, why not plt.bar(x,y, width="5mm") as well?

    At which point do you evaluate the conversion? Since 8.0 == (8.0/2.54)*2.54 is False, I suppose it might matter.

    In total, I think this requires a lot of thought and a clear concept.

  8. wavexx commented on Oct 5, 2018

    @wavexx
    ContributorAuthor
  9. jklymak commented on Oct 5, 2018

    @jklymak
    Member

    There was a big discussion about this in #9226. I didn’t come away from that with many compelling arguments for anything other than allowing simple strings. I think the only issue is that we want to be consistent across the library in what strings are chosen

    I’m not convinced there is any need to worry about the return type units. If folks are going to do math with the return type they can look up whatever conversion they need.

    If at some point we want to be pedantic and include inverse units like dpi I suppose that could happen but we don’t get an issue every few months asking to specify dpi in dots per millimeters, so I think that could be put off.

  10. modified the milestones: v3.1.0, v3.2.0 on Mar 18, 2019
  11. wavexx commented on May 4, 2020

    @wavexx
    ContributorAuthor

    Still waiting patiently for this. It's amazing how anything involving printing is stuck with inches, but I'd expect something a bit better out of a scientific plotting package... :/

  12. jklymak commented on May 4, 2020

    @jklymak
    Member

    Printing is done in points, and a point is 1/72 of an inch. Given there is an easy conversion to centimeters, I don't think there is any appetite for a new way to parse the fig size options. If you wanted to propose a set_figsize_cm thats probably not too hard to add...

  13. 12 remaining items

  14. timhoffm commented on Aug 26, 2020

    @timhoffm
    Member

    @alkhwarizmi What you are scetching is a more general layout system allowing Artists in relative or absolute positions given in various units. This would be a solution to be considered if starting from scratch. Unfortunately, Matplotlib does work differently internally and the general solution would require a major redesign.

    But even when limiting to figure size: Holding hidden state and changing the return value of get_size() based on that can be surprising. Even more so if that would be controlled by a global parameter like rcParams['auto_mm_to_inch'] proposed above.

    If anything, something like #12415 seems most viable to me. My impression is that none of the core developers sees this as a priority, justifying to work on this themselves. It would need an external champion to work through all the details and push it forward. If somebody is interested in working on this, please comment in #12415.

    In #18360 I've written an example for best practices working with different units. This is as good as we can get without introducing new API.

  15. jklymak commented on Aug 26, 2020

    @jklymak
    Member

    looking back, it seems #12415 was close, but a couple of core devs were somewhat negative, and folks stopped reviewing it, and I lost interest compared to other things I thought were more worth harassing potential reviewers for. So, if someone really wants to take the torch up and make a new PR based off #12415, I wouldn't object. In the meantime, I think #18360 is pretty useful.

  16. timhoffm commented on Aug 26, 2020

    @timhoffm
    Member

    If somebody wants to pick up #12415, please comment on that PR. We will then re-review the PR to determine if the concept has fundamental approval among core developers. This makes sure, that your work on the PR can get accepted.

  17. github-actions commented on May 17, 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!

  18. added
    status: closed as inactiveIssues closed by the "Stale" Github Action. Please comment on any you think should still be open.
    on Jun 16, 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

    status: closed as inactiveIssues closed by the "Stale" Github Action. Please comment on any you think should still be open.status: inactiveMarked by the “Stale” Github Action

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions