Skip to content

Feature Request: ability to set hspace/wspace in inches/points in constrained_layout #12690

Open

Description

@djakubosky

It would be nice if, similar to tight_layout h_pad and w_pad, the hspace and wspace of constrained_layout could be set in points or inches rather than fraction of subplot group. This would enable maintaining the same spacing in figure panels of different sizes.

Perhaps there could be a pad_space_units argument.

Activity

  1. ImportanceOfBeingErnest commented on Nov 1, 2018

    @ImportanceOfBeingErnest
    Member

    The w_pad and h_pad of constrained layout are supposed to be in units of inches.

    From the docs:

    w_pad, h_pad: Padding around axes objects.
    Float representing inches. Default is 3./72. inches (3 pts)

    In reality it seems to be some unit which is proportional to inches though.

  2. jklymak commented on Nov 1, 2018

    @jklymak
    Member

    It should just be inches? If it’s not, then I screwed something up.

  3. djakubosky commented on Nov 1, 2018

    @djakubosky
    Author

    There is some inconsistency in these terms between methods,

    w_pad and h_pad in constrained_layout appear to be in inches (and set minimum distances between plots)

    pad, w_pad and h_pad in tight_layout are in units of fraction of fontsize (and set actual distances between the plots)- currently I use this to get exact spacing between subplots by setting the fontsize to 72 point so it can be in inches.

    hspace/wspace in constrained_layout set "Spacing between subplots" in units of "fraction of the size of the subplot group as a whole" which I assume is because they inherit from gridspec.

    It may be a difficult thing to do, but I wondered if constrained_layout wspace and hspace could be specified in inches somehow, as an option- as they seem to set the actual distance between axes INCLUDING their texts.

  4. jklymak commented on Nov 1, 2018

    @jklymak
    Member

    I see - thanks for the reminder...

    1. I'm 98% sure this is possible and relatively straight forward to code up.
    2. The current arguments are not even consistent w/ hspace and space for grid spec, which are fractions of the average subplot width, not the figure/subplotspec width.
    3. I'm not sure what behaviour is more desirable. To my eye, making the gaps bigger as the figure is made bigger is more desirable, but I can see how a fixed spacing is also useful.
    4. I'm 50/50 on adding another kwarg. I actually think things like this could be parsed as strings (i.e. "2.5pc", "30pt", "0.42in", but there is significant resistance to string parsing APIs (largely because they can end up a mess; and also folks like to be able to programatically pass parameters, and having to pack in strings runs people the wrong way.).

    So I'm more than open to looking at this, or helping a PR to implement this, but it'd be good to get a few opinions.

  5. djakubosky commented on Nov 1, 2018

    @djakubosky
    Author

    A few thoughts on your points.

    1. Neat! I think it could be very useful if feasible
    2. I believe the h/wspace arg in constrained_layout makes more sense than that of gridspec- since "average subplot width" is hard to conceptualize in your head, especially if your gridspec is not a simple arrangement.
    3. I think scaling the gaps with figure size is most desirable as default, because I believe most users are probably working with digital images the majority of the time. However, for people interested in precise figures meant to be printed (my reason for raising the feature request), the fixed spacing is a desirable option. In this context, and in general, I believe it should be possible to make figures of different sizes with consistently spaced subplots regardless of gridspec layouts.
    4. you may consider something similar to what is implemented in mpl.transforms.offset_copy() which has a units kwarg that can specify "inches", "points", "dots". I agree that requiring packing in strings could annoy some users.
  6. jklymak commented on Nov 1, 2018

    @jklymak
    Member

    Is the number you want not just hspace = spaceinches/figwidth? At least for a simple layout?

  7. jklymak commented on Nov 1, 2018

    @jklymak
    Member

    The issue w/ a unit kwarg is that its not clear what it pertains to. In this case, there are two pairs of things that may have units (h/wspace and h/wpad)

  8. djakubosky commented on Nov 1, 2018

    @djakubosky
    Author

    Yes, I think this is what I would want- intuitive/convertible. And with regards to the "units" kwarg, I think it should be called something like space_units. I suppose then you could also have a pad_units if you thought it was necessary (though that brings in more kwargs).

  9. ImportanceOfBeingErnest commented on Nov 1, 2018

    @ImportanceOfBeingErnest
    Member

    It should just be inches? If it’s not, then I screwed something up.

    @jklymak It looks like the constrained layout is fine. I was misguided by the axes being at wrong positions in general. I opened #12697 about it.

  10. timhoffm commented on Nov 1, 2018

    @timhoffm
    Member

    -0.5 on additional kwargs for units. Some downsides are already mentioned. Also, it's getting quite verbose and number and unit are closely related, which is not reflected in the API if we split it into two arguments.

    If we really want to support different units, a string hspace='2pt' is still better than hspace=2, hspace_unit='pt'. An alternative would be a tuple hspace=(2, 'pt').

    Do we have an idea how other libraries approach this?

  11. jklymak commented on Nov 1, 2018

    @jklymak
    Member

    No idea about other libraries. But I think the tuple idea is a good one.

  12. djakubosky commented on Nov 1, 2018

    @djakubosky
    Author

    This tuple approach mirrors R libraries for table/grid building: eg gtable, multipanelfigure . Note that these have a units kwarg too- that will set all pad/space args to the same unit. In the case that you don't give them a tuple with a specified unit, unit kwarg provides the default.

  13. Tillsten commented on Nov 2, 2018

    @Tillsten
    Contributor

    From a users point of view, the string approach seems more straightforward. It is shorter and reads better: since I think newcomers will be confused why there is a tuple. Also setting the widths programmatically, the case where the tuple is a little bit better, is quite uncommon and be easily substituted by string interpolation.

  14. jklymak commented on Nov 2, 2018

    @jklymak
    Member

    See #9226 and #12415 for more discussion (in the context of setting figure sizes)....

    @djakubosky did you have any interest in trying to make this work? Looking at the code, I think you'd want to modify _constrained_layout.py/_arrange_subplotspecs. To be honest, I'm not even sure the padding arguments there do what the docs claim they do - I somewhat suspect they are fraction of the figure width, divided by the number of columns, but I've not re-investigated.

    If you can't do it, I'll have a look over the next little while. Exactly how the dimension gets parsed is of course something that can be added on top of a working translation system.

  15. anntzer commented on Nov 2, 2018

    @anntzer
    Contributor

    From a users point of view, the string approach seems more straightforward. It is shorter and reads better: since I think newcomers will be confused why there is a tuple. Also setting the widths programmatically, the case where the tuple is a little bit better, is quite uncommon and be easily substituted by string interpolation.

    Perhaps newcomers will be slightly more puzzled by (2, "cm") than "2cm" (and I'm absolutely not convinced of that), but they will definitely be more puzzled by f"{x}cm" or "{}cm".format(x) or "%scm" % x than by (x, "cm")...

  16. timhoffm commented on Nov 2, 2018

    @timhoffm
    Member

    Both ways have advantages and disadvantages. At some point, someone has to make a decision. I think we should not support both to keep the API cleaner.

  17. djakubosky commented on Nov 2, 2018

    @djakubosky
    Author

    @jklymak I did some digging into what you pointed out, I think I can fix it. I'll fool around with it a little in the next few days. Unless I'm missing something, hspace/wspace are not what they claim, it seems they are literally (hspace/number of rows)- which is passed on and interpreted as a normalized figure coordinate. At any rate, the h_pad, w_pad get converted to normalized figure coordinates from inches at the level of figure.execute_constrained_layout() so I think manipulating the hspace ,wspace there might make sense.

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

  19. added
    status: closed as inactiveIssues closed by the "Stale" Github Action. Please comment on any you think should still be open.
    on Jun 21, 2023
  20. added
    keepItems to be ignored by the “Stale” Github Action
    and removed
    status: inactiveMarked by the “Stale” Github Action
    status: closed as inactiveIssues closed by the "Stale" Github Action. Please comment on any you think should still be open.
    on Jun 21, 2023
  21. jklymak commented on Jun 21, 2023

    @jklymak
    Member

    I reopened this. I think it's still a good idea to allow fixed space margins, it just fell off my radar of things to work on.

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

    keepItems to be ignored by the “Stale” Github Action

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions