Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Automatically Aligned Labels outside Figure with Constrained Layout in Exported File #19152

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

Closed
Firionus opened this issue Dec 19, 2020 · 12 comments
Labels
Good first issue Open a pull request against these issues if there are no active ones! topic: geometry manager LayoutEngine, Constrained layout, Tight layout topic: testing
Milestone

Comments

@Firionus
Copy link

Bug report

Bug summary

When using constrained layout on a specific 3-plot layout with automatically aligned labels, the exported plot has labels outside the page. The image in Jupyter Lab renders fine.

Code for reproduction

import numpy as np
import matplotlib.pyplot as plt

data = [0,1]

fig, (ax3, ax1, ax2) = plt.subplots(3, 1, constrained_layout=True, figsize=(6.4,8), 
    gridspec_kw={"height_ratios":(1, 1, .7)})

ax1.plot(data, data)
ax1.set_ylabel("Label")

ax2.plot(data, data)
ax2.set_ylim(-1.5, 1.5)
ax2.set_ylabel("Label")

ax3.plot(data, data)
ax3.set_ylabel("Label")

fig.align_ylabels(axs=(ax3, ax1, ax2))

fig.savefig("test.pdf")

In savefig, backend="PDF" and backend="PGF" or exporting as .png leads to the same, unexpected outcome for me.

Actual outcome

Exported PDF Screenshot:

image

Expected outcome

Screenshot from Jupyter Notebook:

image

Matplotlib version

  • Operating system: Windows 10 2004 Build 19041.685
  • Matplotlib version: 3.3.3
  • Matplotlib backend (print(matplotlib.get_backend())): module://ipykernel.pylab.backend_inline
  • Python version: 3.7.3
  • Jupyter version (if applicable):
    • jupyter core : 4.6.3
    • jupyter-notebook : 6.1.1
    • qtconsole : 4.7.5
    • ipython : 7.17.0
    • ipykernel : 5.3.4
    • jupyter client : 6.1.6
    • jupyter lab : 2.2.4
    • nbconvert : 5.6.1
    • ipywidgets : 7.5.1
    • nbformat : 5.0.7
    • traitlets : 4.3.3
  • Other libraries:

Matplotlib installed via pip. Python installed via Windows installer from python.org.

Workaround

Use manual label positions as explained in https://matplotlib.org/gallery/pyplots/align_ylabels.html

@jklymak jklymak added topic: geometry manager LayoutEngine, Constrained layout, Tight layout topic: testing Good first issue Open a pull request against these issues if there are no active ones! labels Dec 19, 2020
@jklymak
Copy link
Member

jklymak commented Dec 19, 2020

Thanks for the bug report. This (coincidentally) appears to have been fixed by #17494 and will be in the 3.4 release, so I don't think there is an action item here, except perhaps to add a test for this? I'll add a "Good first issue" here in case someone wants to add a test. Probably can be done w/o an image comparison, but I'd have to play with it to be sure.

@jklymak jklymak added this to the v3.4.0 milestone Dec 19, 2020
@ghost
Copy link

ghost commented Dec 28, 2020

changing ax2.set_ylim(-1.5, 1.5)

to ax2.set_ylim(1.5) solves this issue?

@Firionus
Copy link
Author

Yes, changing to ax2.set_ylim(1.5) solves the issue, but also changes the axis limits, which may not be desired. The layout problem is rather sensitive to the content of the y-axis labels.

@Hathaway2010
Copy link

I'm brand new to open source — if I were looking to write a test, what files should I look at? Thank you!

@jklymak
Copy link
Member

jklymak commented Jan 19, 2021

@Hathaway2010 Please have a look at https://matplotlib.org/devel/index.html and https://github.com/matplotlib/matplotlib/tree/master/lib/matplotlib/tests I think maybe test_figure.py is where the align_ylabel tests are? Thanks!

@Hathaway2010
Copy link

Thank you! I'll see if I can do something in the next few days!

@Hathaway2010
Copy link

Hathaway2010 commented Jan 26, 2021

Hi! I'm pretty sure I've found a test that does the trick: after saving the pdf in the code for reproduction, I do

after_align = (ax1.yaxis.label.get_window_extent(),
                      ax2.yaxis.label.get_window_extent(),
                      ax3.yaxis.label.get_window_extent())

assert round(after_align[0].x0, 5) == round(after_align[1].x0, 5) == round(after_align[2].x0, 5) > 1

When I use an old version of matplotlib, this detects that the top two labels are 1) not aligned with the third (i.e., the three aren't approximately equal) and 2) have gone off the page (have an x0 greater than 1). When running pytest on my branch of the current repository, everything seems to be fine — the test passes, and the saved PDF looks fine.

I have two beginner's questions:

  1. On https://matplotlib.org/3.2.1/devel/testing.html it says "Some tests have internal side effects that need to be cleaned up after their execution (such as created figures or modified rc params). The pytest fixture mpl_test_settings() will automatically clean these up; there is no need to do anything further." When I run this test using pytest, at least singly instead of as part of the test suite, I am left with that PDF. Is there a particular path to which the PDF should be saved so it will be cleaned up afterward, or something else I need to do to make sure it doesn't hang around?
  1. You pointed me (with some uncertainty) to test_figure.py. However, I see there's also a test_constrainedlayout.py — would it be more appropriate to put my test in the latter document? (I do see a few tests in test_figure.py that include constrained layout)

Many thanks, and sorry for my ignorance.

@Firionus
Copy link
Author

Hey,
thanks for taking this on!

I think your code example has lost some linebreaks. If you want line breaks in code, use a Fenced Code Block with three backticks or tildes.

Example:

``` 
line1
line2
``` 

renders as

line1
line2

@Hathaway2010
Copy link

fixed, thank you!

@jklymak
Copy link
Member

jklymak commented Jan 26, 2021

Does this need to be saved as pdf? Or do you just need to trigger a draw via fig.canvas.draw()

Yes, it seems test_constrained_layout.py is a good place to put this.

@Hathaway2010
Copy link

fig.canvas.draw() seems to do just fine, thank you and oops! I've moved the test to the correct file and hope to submit a pull request within the hour.

@jklymak
Copy link
Member

jklymak commented Feb 4, 2021

Closed by #19373

@jklymak jklymak closed this as completed Feb 4, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Good first issue Open a pull request against these issues if there are no active ones! topic: geometry manager LayoutEngine, Constrained layout, Tight layout topic: testing
Projects
None yet
Development

No branches or pull requests

3 participants