-
-
Notifications
You must be signed in to change notification settings - Fork 7.9k
ENH: fig.set_size to allow non-inches units #12415
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
lib/matplotlib/figure.py
Outdated
@@ -883,8 +929,7 @@ def set_size_inches(self, w, h=None, forward=True): | |||
|
|||
# the width and height have been passed in as a tuple to the first | |||
# argument, so unpack them | |||
if h is None: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we still need this special casing here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, bad cut and paste job...
lib/matplotlib/figure.py
Outdated
if h is None: | ||
w, h = w | ||
if isinstance(w, str): | ||
temp = w |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what is temp for?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry @tacaswell I didn't really proofread it all - I was more interested in if the API would fly. It also needs tests and more documentation...
60d94fd
to
2f9b45d
Compare
This has come up before and I am still not convinced this is a good idea (but am more convinced than I used to be). |
Any other opinions one way or another for this? I'll give it +1 because I don't think its too crufty, and its backcompatble. @tacaswell seems -0.5? |
To sum up, my recommendation is:
|
Please don't deprecate |
@ImportanceOfBeingErnest I see your point. OTOH two functions are clutter in the long run. Maybe just add a note to the docstring that |
@timhoffm I agree - we need something for the |
@jklymak Basically, +1 for supporting the three-tuple figsize. However, I'm still -0.5 on string values. Both APIs need to be discussed with other devs. It's likely that there will still be changes. You might want to wait with the actual implementation until the API is finally decided upon. Otherwise, you may have duplicate coding work. Just saying. Of course you are free to update proof-of-concept code as we discuss 😄 . |
I agree with most of what @timhoffm and @ImportanceOfBeingErnest said (which are the reasons I am not convinced on this). Balancing {"passing non-inch values to I like @timhoffm 's suggestion of letting the |
@tacaswell actually, I'm not advocating the "pair of strings" option. I find that a bit unconventional. And it's basically redundant (=not needed) if we have the (width, height, unit) triple. |
I think |
My vote would be for default inches as the float-only API. Historically it’s what we have offered, internally it’s what we use, and I’m not in favour of some sort of unitized getter for figure size. Anyone who needs to programmatically get the size of a figure is surely capable of converting in their code. Thus allowing inches only as the default is good because it lets the user know that’s our default and internal convention. The units are just there as a mild convenience. |
fig, ax = plt.subplots(figsize=(500, 300, 'px')) |
@@ -2075,3 +2075,26 @@ def _check_and_log_subprocess(command, logger, **kwargs): | |||
.format(command, exc.output.decode('utf-8'))) | |||
logger.debug(report) | |||
return report | |||
|
|||
|
|||
def _print_unit(st, dpi=None): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
function name seems a bit weird?
Convert from a string with a number and units into inches | ||
""" | ||
print_units = {'cm': 2.54, 'pt': 72.0, 'mm': 25.4, 'in': 1.0} | ||
if len(st) > 2: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is that a leftover of supporting "2cm"?
edit: I see that's not removed yet? (not a big deal, just checking)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not leftover yet. I still think it’s an ok API to have both
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No problem, we can discuss this over the call.
@@ -862,19 +870,85 @@ def figimage(self, X, xo=0, yo=0, alpha=None, norm=None, cmap=None, | |||
self.stale = True | |||
return im | |||
|
|||
def set_size(self, w, h=None, units=None, forward=True): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now that we're introducing a new API, let's decide whether we want set_size((w, h))
or set_size(w, h)
but don't support both. (I have a mild preference for set_size((w, h))
, as that fits the setter model better (figure.set(size=(w, h))
)).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don’t think it necessarily is a good idea to make it inconsistent with the existing API. Why do we have to enforce a tuple?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not going to fight too much over this specific case as we're just following a preexisting API, but in general I think we should aim for functions that have a single well-define signature (either taking two floats as separate arguments, or a single pair); otherwise that's how we end up with the mess that's custom arg parsing for plot(), quiver() and friends...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree that this should be decided. Unfortunately there are good reasons for both.
set_size((w, h))
is more difficult to type and read. It feels a bit artificial, also given that ax.set_xlim(left, right)
has a similar signature and I wouldn't vote for changing that.
OTOH, set_size(size)
would allow to trivially support size=(6, 4, "cm")
throughout the whole library and in all figure-creating functions. If we just have set_size(w, h, unit)
we might need some explicit conversion of the tuple.
All over, I have a mild preference for set_size(w, h)
.
Speaking of which, I'm also fine with the "both" solution set_size(self, w, h=None)
, basically because we already have precedence. The documentation is more cumbersome, but all use-cases can be covered. So to me, it would be ok to use this and defer a general decision.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, set_xlim((left, right))
also works...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah the boo(x, y)
= boo((x, y))
API is quite prevalent. I agree it can make parsing the args a bit of a nuisance, though to me the basic problem w/ plot
is the fact we allow, plot(x1, y1, x2, y2)
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If it was just that. We also have plot(x1, y1, fmt1, x2, y2, fmt2)
and even plot(y1, fmt1, y2, fmt2)
. Welcome to the Matlab way of thinking. But we are getting off-topic.
OK, thanks for everyone's work on this. In the spirit of keeping things simple, I think folks will have to make due with converting in their downstream code. If anyone wants to take this up, though, they should feel free. |
Reviving the spirit of matplotlib#12402 and matplotlib#12415, because both had significant user votes on GitHub. This PR is intentionally minimal to only expand the `figsize` parameter when creating a figure. This should be the most relevant use case. Later changing the figure size or reading it is probably less necessary. The minimal approach removes the need to track and return sizes. It is just an enhanced specification capability which directly parses to the internally used inch unit.
Reviving the spirit of matplotlib#12402 and matplotlib#12415, because both had significant user votes on GitHub. This PR is intentionally minimal to only expand the `figsize` parameter when creating a figure. This should be the most relevant use case. Later changing the figure size or reading it is probably less necessary. The minimal approach removes the need to track and return sizes. It is just an enhanced specification capability which directly parses to the internally used inch unit.
Reviving the spirit of matplotlib#12402 and matplotlib#12415, because both had significant user votes on GitHub. This PR is intentionally minimal to only expand the `figsize` parameter when creating a figure. This should be the most relevant use case. Later changing the figure size or reading it is probably less necessary. The minimal approach removes the need to track and return sizes. It is just an enhanced specification capability which directly parses to the internally used inch unit.
Reviving the spirit of matplotlib#12402 and matplotlib#12415, because both had significant user votes on GitHub. This PR is intentionally minimal to only expand the `figsize` parameter when creating a figure. This should be the most relevant use case. Later changing the figure size or reading it is probably less necessary. The minimal approach removes the need to track and return sizes. It is just an enhanced specification capability which directly parses to the internally used inch unit.
Reviving the spirit of matplotlib#12402 and matplotlib#12415, because both had significant user votes on GitHub. This PR is intentionally minimal to only expand the `figsize` parameter when creating a figure. This should be the most relevant use case. Later changing the figure size or reading it is probably less necessary. The minimal approach removes the need to track and return sizes. It is just an enhanced specification capability which directly parses to the internally used inch unit.
Reviving the spirit of matplotlib#12402 and matplotlib#12415, because both had significant user votes on GitHub. This PR is intentionally minimal to only expand the `figsize` parameter when creating a figure. This should be the most relevant use case. Later changing the figure size or reading it is probably less necessary. The minimal approach removes the need to track and return sizes. It is just an enhanced specification capability which directly parses to the internally used inch unit.
Reviving the spirit of matplotlib#12402 and matplotlib#12415, because both had significant user votes on GitHub. This PR is intentionally minimal to only expand the `figsize` parameter when creating a figure. This should be the most relevant use case. Later changing the figure size or reading it is probably less necessary. The minimal approach removes the need to track and return sizes. It is just an enhanced specification capability which directly parses to the internally used inch unit.
Reviving the spirit of matplotlib#12402 and matplotlib#12415, because both had significant user votes on GitHub. This PR is intentionally minimal to only expand the `figsize` parameter when creating a figure. This should be the most relevant use case. Later changing the figure size or reading it is probably less necessary. The minimal approach removes the need to track and return sizes. It is just an enhanced specification capability which directly parses to the internally used inch unit.
PR Summary
cross-ref #12402, #9226, #1369
Work in progress for opinions....
EDIT: added
figsize
three-tupleEDIT: added units kwarg. See last example....
a. this is a very light-weight change that adds convenience for the meterically inclined.
b. if we want to add support for print units from some sort of units library, those can be converted too. i.e. we aren't closing the door on more sophisticated APIs.
PR Checklist