You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Feature Request: ability to set hspace/wspace in inches/points in constrained_layout #12690
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.
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_layoutwspace and hspace could be specified in inches somehow, as an option- as they seem to set the actual distance between axes INCLUDING their texts.
I'm 98% sure this is possible and relatively straight forward to code up.
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.
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.
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.
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.
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.
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.
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)
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).
-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?
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.
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.
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.
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")...
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.
@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.
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!
Activity
ImportanceOfBeingErnest commentedon Nov 1, 2018
The
w_padandh_padof constrained layout are supposed to be in units of inches.From the docs:
In reality it seems to be some unit which is proportional to inches though.jklymak commentedon Nov 1, 2018
It should just be inches? If it’s not, then I screwed something up.
djakubosky commentedon Nov 1, 2018
There is some inconsistency in these terms between methods,
w_padandh_padin constrained_layout appear to be in inches (and set minimum distances between plots)pad,w_padandh_padintight_layoutare 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/wspaceinconstrained_layoutset "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_layoutwspaceandhspacecould be specified in inches somehow, as an option- as they seem to set the actual distance between axes INCLUDING their texts.jklymak commentedon Nov 1, 2018
I see - thanks for the reminder...
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.
djakubosky commentedon Nov 1, 2018
A few thoughts on your points.
unitskwarg that can specify "inches", "points", "dots". I agree that requiring packing in strings could annoy some users.jklymak commentedon Nov 1, 2018
Is the number you want not just
hspace = spaceinches/figwidth? At least for a simple layout?jklymak commentedon Nov 1, 2018
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)
djakubosky commentedon Nov 1, 2018
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).
ImportanceOfBeingErnest commentedon Nov 1, 2018
@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.
timhoffm commentedon Nov 1, 2018
-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 thanhspace=2, hspace_unit='pt'. An alternative would be a tuplehspace=(2, 'pt').Do we have an idea how other libraries approach this?
jklymak commentedon Nov 1, 2018
No idea about other libraries. But I think the tuple idea is a good one.
djakubosky commentedon Nov 1, 2018
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.
Tillsten commentedon Nov 2, 2018
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.
jklymak commentedon Nov 2, 2018
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.
anntzer commentedon Nov 2, 2018
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 byf"{x}cm"or"{}cm".format(x)or"%scm" % xthan by(x, "cm")...timhoffm commentedon Nov 2, 2018
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.
djakubosky commentedon Nov 2, 2018
@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/wspaceare 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 offigure.execute_constrained_layout()so I think manipulating thehspace,wspacethere might make sense.github-actions commentedon May 22, 2023
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!
jklymak commentedon Jun 21, 2023
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.