Skip to content
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

constrained-layout gives wrong results when explicitly equal width ratios are set #17304

Closed
anntzer opened this issue May 2, 2020 · 2 comments · Fixed by #17306
Closed

constrained-layout gives wrong results when explicitly equal width ratios are set #17304

anntzer opened this issue May 2, 2020 · 2 comments · Fixed by #17306
Labels
topic: geometry manager LayoutEngine, Constrained layout, Tight layout
Milestone

Comments

@anntzer
Copy link
Contributor

anntzer commented May 2, 2020

Bug report

Bug summary

When passing width_ratios = [1, 1, 1] instead of not passing it at all (which should be synonymous), constrained_layout sometimes gives incorrect results.

Code for reproduction

import matplotlib as mpl
from matplotlib import pyplot as plt, gridspec, testing

mpl.rcdefaults()
mpl.style.use(["classic", "_classic_test_patch"])
mpl.testing.set_font_settings_for_testing()

def example_plot(ax, fontsize=12):
    ax.plot([1, 2])
    ax.locator_params(nbins=3)
    ax.set_xlabel('x-label', fontsize=fontsize)
    ax.set_ylabel('y-label', fontsize=fontsize)
    ax.set_title('Title', fontsize=fontsize)

fig = plt.figure(constrained_layout=True)
gs = gridspec.GridSpec(3, 3, figure=fig)

ax1 = fig.add_subplot(gs[0, 0])
ax2 = fig.add_subplot(gs[0, 1:])
ax3 = fig.add_subplot(gs[1:, 0:2])
ax4 = fig.add_subplot(gs[1:, -1])

for ax in fig.axes:
    example_plot(ax)

fig.savefig("/tmp/cl1.png")

fig = plt.figure(constrained_layout=True)
gs = gridspec.GridSpec(3, 3, figure=fig,
                       width_ratios=[1, 1, 1], height_ratios=[1, 1, 1])

ax1 = fig.add_subplot(gs[0, 0])
ax2 = fig.add_subplot(gs[0, 1:])
ax3 = fig.add_subplot(gs[1:, 0:2])
ax4 = fig.add_subplot(gs[1:, -1])

for ax in fig.axes:
    example_plot(ax)

fig.savefig("/tmp/cl2.png")

plt.show()

Actual outcome

cl1.png
cl1

cl2.png
cl2

Clearly in cl2.png the widths are not in the ratios 1:1:1 but (approximately) 1:2:1.

This is likely a floating point error; it is extremely sensitive to conditions, in particular the call to set_font_settings_for_reproducibility (which just sets some font-related rcs) is necessary to observe this.

Expected outcome

twice the same image

Matplotlib version

  • Operating system: archlinux
  • Matplotlib version: master
  • Matplotlib backend (print(matplotlib.get_backend())): agg
  • Python version: 38
  • Jupyter version (if applicable): no
  • Other libraries:
@jklymak
Copy link
Member

jklymak commented May 2, 2020

Yes agreed. The constraints are probably a bit flakey here and find the wrong solution sometimes. Since this is pretty reproducible I should be able to track down.

Note this is a pretty nasty subplot layout. I wouldn’t block any releases on this use case. If you wanted to set the tolerance really high for that test for the other PR that would probably be acceptable.

@anntzer
Copy link
Contributor Author

anntzer commented May 2, 2020

I don't think the other PR is particularly urgent either, I'm fine just waiting for you on this :-)

@jklymak jklymak mentioned this issue May 2, 2020
6 tasks
@QuLogic QuLogic added this to the v3.3.0 milestone May 4, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
topic: geometry manager LayoutEngine, Constrained layout, Tight layout
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants