Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Closed
jklymak wants to merge4 commits intomatplotlib:masterfromjklymak:enh-fig-set-size

Conversation

jklymak
Copy link
Member

@jklymakjklymak commentedOct 5, 2018
edited
Loading

PR Summary

cross-ref#12402,#9226,#1369

Work in progress for opinions....

EDIT: addedfigsize three-tuple

EDIT: 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.

importnumpyasnpimportmatplotlib.pyplotaspltfig,ax=plt.subplots()fig.set_size((5,3))print(fig.get_size_inches())fig.set_size((5,3,'in'))print(fig.get_size_inches())fig.set_size((12.7,7.62,'cm'))print(fig.get_size_inches())fig.set_size(5,3)print(fig.get_size_inches())fig.set_size('5in','3in')print(fig.get_size_inches())fig.set_size('12.7cm','7.62cm')print(fig.get_size_inches())fig.set_size('127mm','76.2mm')print(fig.get_size_inches())fig.set_size('360pt','216pt')print(fig.get_size_inches())fig.set_size(360,216,units='pt')print(fig.get_size_inches())
[5. 3.][5. 3.][5. 3.][5. 3.][5. 3.][5. 3.][5. 3.][5. 3.]
importmatplotlib.pyplotaspltfig,ax=plt.subplots(figsize=(12.7,7.62,'cm'))print(fig.get_size_inches())fig,ax=plt.subplots(figsize=('12.7cm','7.62cm'))print(fig.get_size_inches())fig,ax=plt.subplots(figsize=(500,300,'px'))print(fig.get_size_inches())
[5. 3.][5. 3.][5. 3.]

PR Checklist

  • Has Pytest style unit tests
  • Code isFlake 8 compliant
  • New features are documented, with examples if plot related
  • Documentation is sphinx and numpydoc compliant
  • Added an entry to doc/users/next_whats_new/ if major new feature (follow instructions in README.rst there)
  • Documented in doc/api/api_changes.rst if API changed in a backward-incompatible way

@@ -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:
Copy link
Member

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.

Copy link
MemberAuthor

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...

if h is None:
w, h = w
if isinstance(w, str):
temp = w
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

what is temp for?

Copy link
MemberAuthor

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...

@tacaswelltacaswell added this to thev3.1 milestoneOct 5, 2018
@tacaswell
Copy link
Member

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).

@jklymak
Copy link
MemberAuthor

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?

@timhoffm
Copy link
Member

timhoffm commentedOct 7, 2018
edited
Loading

  • I find it ok to be able to specify the size in different units, but still do all the internal handling and the returned size in inches. This is just a convenience converter for the inputs. No need to make all the internal logic and getters unit-aware. After all, setting the size is much more common than querying the size.

  • Personally, I don't useFigure.set_size_inches but only thefigsize kwarg. Since this is all about convenience, I'm afraid just addingFigure.set_size will not reach the goal unless we're going to makefigsize accept units as well.

    fig, ax = plt.subplots(figsize=(8/2.54, 6/2.54))

    is still more convenient than

    fig, ax = plt.subplots()fig.set_size(8, 6, unit='cm')
  • We should not haveFigure.set_size andFigure.set_size_inches as equal options. The should be only one way, meaning we would have to deprecateFigure.set_size_inches.

  • I'm a bit worried about the permitted values.set_size(8, 6, unit='cm') seems perfectly reasonable.set_size('8cm', '6cm') is a bit more unconventional. If it was just aboutset_size, I wouldn't allow string values. However, that poses the question onplt.subplots(figsize=). Here you would either haveplt.subplots(figsize=('8cm', '6cm')) or you would need a separate kwargplt.subplots(figsize=(8, 6), figunit='cm'). I'm -0.5 on string arguments and -0.8 on extra figure keywords.

    Another alternative would beplt.subplots(figsize=(8, 6, 'cm')), which is not great, but IMHO the best compromise to specify units. Getting a good interface forFigure() andsubplots() is the crucial point to me. Otherwise, unit support does not have a real benefit.

To sum up, my recommendation is:

  • Figure.set_size(width : float, height : float, unit='inch', ...)
  • deprecateFigure.set_size_inches
  • acceptFigure(figsize=(8, 6, 'cm'))

@ImportanceOfBeingErnest
Copy link
Member

Please don't deprecateFigure.set_size_inches. The number of people who will then need to change their code is certainly higher than the number of people who benefit from introducing the metric stuff.
So from my side -10 on deprecating anything here, ±0 on adding functionality.

tacaswell reacted with thumbs up emoji

@timhoffm
Copy link
Member

@ImportanceOfBeingErnest I see your point. OTOH two functions are clutter in the long run. Maybe just add a note to the docstring thatset_size() is preferred overset_size_inches() - similar to how we don't deprecate pylab. And maybe maybe deprecated in 4.0?

alkhwarizmi reacted with thumbs up emoji

@jklymak
Copy link
MemberAuthor

@timhoffm I agree - we need something for thefigsize kwarg. This change accepts three-tuple or two-tuple of strings (as well as keeping old behaviour)

@timhoffm
Copy link
Member

@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 😄 .

@tacaswell
Copy link
Member

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 toset_size_inches", "we don't want to have two functions that do the same things", "we can not deprecatedset_size_inches} has been the sticking point on this before.

I like@timhoffm 's suggestion of letting thefigsize kwarg take a triple, a pair of inches, or a pair of strings maybe the best path forward (and leavingset_size_inches alone). It extends the API in a pretty natural way, is back compatible, adds no new names, and does not have any weird name / input clashes.

timhoffm reacted with thumbs up emoji

@timhoffm
Copy link
Member

@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.

@anntzer
Copy link
Contributor

I thinkfigsize=(x, y, "cm") looks ok ((x, y, "px") may be nice to have too).
I'd still introduceset_size and "deprecate-in-docs" (à la pylab)set_size_inches but that's a separate point. (But of course then the question is whetherset_size(x, y) should work with the meaning ofset_size(x, y, "in")... I guess we can always postpone this question to later :))

@jklymak
Copy link
MemberAuthor

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’mnot 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.

timhoffm and anntzer reacted with thumbs up emoji

@jklymak
Copy link
MemberAuthor

px now works (if dpi is set):

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):
Copy link
Contributor

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:
Copy link
Contributor

@anntzeranntzerOct 7, 2018
edited
Loading

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)

Copy link
MemberAuthor

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

Copy link
Contributor

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):
Copy link
Contributor

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 wantset_size((w, h)) orset_size(w, h) but don't support both. (I have a mild preference forset_size((w, h)), as that fits the setter model better (figure.set(size=(w, h)))).

Copy link
MemberAuthor

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?

Copy link
Contributor

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...

Copy link
Member

@timhoffmtimhoffmOct 8, 2018
edited
Loading

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 thatax.set_xlim(left, right) has a similar signature and I wouldn't vote for changing that.

OTOH,set_size(size) would allow to trivially supportsize=(6, 4, "cm") throughout the whole library and in all figure-creating functions. If we just haveset_size(w, h, unit) we might need some explicit conversion of the tuple.

All over, I have a mild preference forset_size(w, h).

Speaking of which, I'm also fine with the "both" solutionset_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.

Copy link
Contributor

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...

Copy link
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Yeah theboo(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).

Copy link
Member

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 haveplot(x1, y1, fmt1, x2, y2, fmt2) and evenplot(y1, fmt1, y2, fmt2). Welcome to the Matlab way of thinking. But we are getting off-topic.

jklymak reacted with laugh emoji
@jklymak
Copy link
MemberAuthor

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.

MrGibus, radumas, justin-m-schmidt, maciejskorski, muellermartin, and michaelweinold reacted with thumbs down emoji

timhoffm added a commit to timhoffm/matplotlib that referenced this pull requestFeb 12, 2025
Reviving the spirit ofmatplotlib#12402 andmatplotlib#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.
@jklymakjklymak deleted the enh-fig-set-size branchFebruary 12, 2025 15:56
timhoffm added a commit to timhoffm/matplotlib that referenced this pull requestFeb 12, 2025
Reviving the spirit ofmatplotlib#12402 andmatplotlib#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.
timhoffm added a commit to timhoffm/matplotlib that referenced this pull requestFeb 12, 2025
Reviving the spirit ofmatplotlib#12402 andmatplotlib#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.
timhoffm added a commit to timhoffm/matplotlib that referenced this pull requestFeb 12, 2025
Reviving the spirit ofmatplotlib#12402 andmatplotlib#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.
timhoffm added a commit to timhoffm/matplotlib that referenced this pull requestMar 10, 2025
Reviving the spirit ofmatplotlib#12402 andmatplotlib#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.
timhoffm added a commit to timhoffm/matplotlib that referenced this pull requestMar 13, 2025
Reviving the spirit ofmatplotlib#12402 andmatplotlib#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.
timhoffm added a commit to timhoffm/matplotlib that referenced this pull requestMar 15, 2025
Reviving the spirit ofmatplotlib#12402 andmatplotlib#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.
timhoffm added a commit to timhoffm/matplotlib that referenced this pull requestApr 6, 2025
Reviving the spirit ofmatplotlib#12402 andmatplotlib#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.
Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment
Reviewers

@tacaswelltacaswelltacaswell left review comments

@anntzeranntzeranntzer left review comments

@timhoffmtimhoffmtimhoffm left review comments

Assignees
No one assigned
Projects
None yet
Milestone
v3.2.0
Development

Successfully merging this pull request may close these issues.

5 participants
@jklymak@tacaswell@timhoffm@ImportanceOfBeingErnest@anntzer

[8]ページ先頭

©2009-2025 Movatter.jp