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

tight_layout support for subfigure#26108

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

Open
leejjoon wants to merge1 commit intomatplotlib:main
base:main
Choose a base branch
Loading
fromleejjoon:fix-subfigure-tightlayout

Conversation

leejjoon
Copy link
Contributor

PR summary

TightLayoutEngine frommatplotlib.layout_engine fails when called with a subfigure. The PR is an attempt to make it to work with subfigures.

Note that, unlikeFigure,Subfigure class does not have a method oftight_layout. So, we need to manually create an instance ofTightLayoutEngine and call it with a subfigure. Here is a simple example.

importmatplotlib.pyplotaspltfig=plt.figure()fig.subplotpars.bottom=0.3subfigs=fig.subfigures(3,3)sfig=subfigs[0,0]sfig.patch.set_fc("y")ax=sfig.subplots(1,1)frommatplotlib.layout_engineimportTightLayoutEngineengine=TightLayoutEngine()engine.execute(sfig)plt.show()

test_subfigure_tight_layout

PR checklist

@jklymak
Copy link
Member

Strongly suggest using layout='constrained' for similar figure layouts.

@leejjoon
Copy link
ContributorAuthor

Strongly suggest using layout='constrained' for similar figure layouts.

Yes, I know the constrained layout works fine with subfigures. But for my "real" use case (which requires different subfigures have some of their subplotpars synced so that their axes align), I found it was more straight forward to to call tight_layout and then to tweak subplotpars. If this is something we can already do with the constrained layout, I will be happy to learn how.

@rcomer
Copy link
Member

rcomer commentedJun 12, 2023
edited
Loading

You can trigger a draw and then turn constrained layout off if that helps?
https://matplotlib.org/devdocs/users/explain/axes/constrainedlayout_guide.html#manually-turning-off-constrained-layout

@leejjoon
Copy link
ContributorAuthor

And is there a way to align axes in different subfigures after that? With tight_layout, I run tight_layout for each of subfigures (they are set to have independent subplotpar attributes), take the maximum value ofsubplotpar.left of all subfigures, for example, and then apply that value to all subfigures.

By the way, independent of this can be done with the constrained layout, I think it is worthwhile to make TightLayoutEngine to support subfigures, given the fixes are rather straightforward.

@jklymak
Copy link
Member

It would be easier to see what you are asking with an example.

There is definitely no harm in making tight_layout work with subfigures if it doesn't require a lot of new knobs.

@@ -2219,6 +2219,12 @@ def __init__(self, parent, subplotspec, *,
self._set_artist_props(self.patch)
self.patch.set_antialiased(False)

def get_size_inches(self):
Copy link
Member

Choose a reason for hiding this comment

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

This needs to be added to thefigure.pyi file.

How odd do we think that it is forSubFigure to haveget_size_inches but notset_size_inches? I'm leaning towards that it is OK, with a small thought of "we should implementset_size_inches that raises and says you have to go talk to the (grand-)parent figure.

Copy link
Member

Choose a reason for hiding this comment

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

I actually think that this should be private (and have a similar private method for the top level Figure that the publicget_size_inches calls, and then uses where we need the subfigure size can call the private method instead.

Copy link
ContributorAuthor

Choose a reason for hiding this comment

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

Ok, I will introduce an private method (so noSubFigure.get_size_inches).@tacaswell : Do you think we still need to consider some sort ofset_size_inches method (likely private) that shows a reasonable error message?

Copy link
Member

Choose a reason for hiding this comment

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

If the method is private, I do not have concerns about the missing setter.

@tacaswelltacaswell added this to thev3.8.0 milestoneJun 12, 2023
Copy link
Member

@jklymakjklymak left a comment

Choose a reason for hiding this comment

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

I think this also needs a test. I'm still not entirely clear what you are proposing the public API for this is? just attaching an engine to a single subfigure and running tight_layout on the subfigure?

@@ -2219,6 +2219,12 @@ def __init__(self, parent, subplotspec, *,
self._set_artist_props(self.patch)
self.patch.set_antialiased(False)

def get_size_inches(self):
Copy link
Member

Choose a reason for hiding this comment

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

I actually think that this should be private (and have a similar private method for the top level Figure that the publicget_size_inches calls, and then uses where we need the subfigure size can call the private method instead.

@leejjoon
Copy link
ContributorAuthor

I think this also needs a test. I'm still not entirely clear what you are proposing the public API for this is? just attaching an engine to a single subfigure and running tight_layout on the subfigure?

For the public API, I am open to any suggestions. I personally think it is not necessary to introduce new public api. I don't expectTightLayoutEngine to be as robust asConstrained LayoutEnging for subfigures. On the other hand, it would be good if theTightLayoutEngine handles a figure with subfigures better, at least for simple cases.

I will push some more changes, including tests.

@jklymak
Copy link
Member

@leejjoon did you want to push forward with this?

For your use case, as I understand it, I would personally juts keep the axes in the same layout versus having them in subfigures. The idea of subfigures is that the layouts between the subfigures are independent. Of course if you are after a very specific layout - say with a larger column separation between columns of axes, then maybe subfigures+subplotpars is a reasonable way to go. Though even for that use case, I'd probably use width_ratios and blank subplots:

import numpy as npimport matplotlib.pyplot as pltfig, axs = plt.subplot_mosaic([['a', 'b', '.', 'c', 'd'],                         ['e', 'f', '.', 'g', 'h']                         ], width_ratios=[1, 1, 0.25, 1, 1],                         layout='constrained')for ax in axs:    axs[ax].set_xticks([])    axs[ax].set_yticks([])plt.show()

Figure_1

However, I appreciate that there are many other reasons you may want to use subfigures.

@QuLogicQuLogic modified the milestones:v3.9.0,v3.10.0Mar 27, 2024
@ksundenksunden modified the milestones:v3.10.0,v3.11.0Sep 18, 2024
Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment
Reviewers

@tacaswelltacaswelltacaswell left review comments

@jklymakjklymakjklymak left review comments

At least 1 approving review is required to merge this pull request.

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

Successfully merging this pull request may close these issues.

6 participants
@leejjoon@jklymak@rcomer@tacaswell@QuLogic@ksunden

[8]ページ先頭

©2009-2025 Movatter.jp