Spaces:
Running
Running
PerceptionLabPortable
/
python_embed
/Lib
/site-packages
/matplotlib
/tests
/test_constrainedlayout.py
| import gc | |
| import platform | |
| import numpy as np | |
| import pytest | |
| import matplotlib as mpl | |
| from matplotlib.testing.decorators import image_comparison | |
| import matplotlib.pyplot as plt | |
| import matplotlib.transforms as mtransforms | |
| from matplotlib import gridspec, ticker | |
| pytestmark = [ | |
| pytest.mark.usefixtures('text_placeholders') | |
| ] | |
| def example_plot(ax, fontsize=12, nodec=False): | |
| ax.plot([1, 2]) | |
| ax.locator_params(nbins=3) | |
| if not nodec: | |
| ax.set_xlabel('x-label', fontsize=fontsize) | |
| ax.set_ylabel('y-label', fontsize=fontsize) | |
| ax.set_title('Title', fontsize=fontsize) | |
| else: | |
| ax.set_xticklabels([]) | |
| ax.set_yticklabels([]) | |
| def example_pcolor(ax, fontsize=12): | |
| dx, dy = 0.6, 0.6 | |
| y, x = np.mgrid[slice(-3, 3 + dy, dy), | |
| slice(-3, 3 + dx, dx)] | |
| z = (1 - x / 2. + x ** 5 + y ** 3) * np.exp(-x ** 2 - y ** 2) | |
| pcm = ax.pcolormesh(x, y, z[:-1, :-1], cmap='RdBu_r', vmin=-1., vmax=1., | |
| rasterized=True) | |
| ax.set_xlabel('x-label', fontsize=fontsize) | |
| ax.set_ylabel('y-label', fontsize=fontsize) | |
| ax.set_title('Title', fontsize=fontsize) | |
| return pcm | |
| def test_constrained_layout1(): | |
| """Test constrained_layout for a single subplot""" | |
| fig = plt.figure(layout="constrained") | |
| ax = fig.add_subplot() | |
| example_plot(ax, fontsize=24) | |
| def test_constrained_layout2(): | |
| """Test constrained_layout for 2x2 subplots""" | |
| fig, axs = plt.subplots(2, 2, layout="constrained") | |
| for ax in axs.flat: | |
| example_plot(ax, fontsize=24) | |
| def test_constrained_layout3(): | |
| """Test constrained_layout for colorbars with subplots""" | |
| fig, axs = plt.subplots(2, 2, layout="constrained") | |
| for nn, ax in enumerate(axs.flat): | |
| pcm = example_pcolor(ax, fontsize=24) | |
| if nn == 3: | |
| pad = 0.08 | |
| else: | |
| pad = 0.02 # default | |
| fig.colorbar(pcm, ax=ax, pad=pad) | |
| def test_constrained_layout4(): | |
| """Test constrained_layout for a single colorbar with subplots""" | |
| fig, axs = plt.subplots(2, 2, layout="constrained") | |
| for ax in axs.flat: | |
| pcm = example_pcolor(ax, fontsize=24) | |
| fig.colorbar(pcm, ax=axs, pad=0.01, shrink=0.6) | |
| def test_constrained_layout5(): | |
| """ | |
| Test constrained_layout for a single colorbar with subplots, | |
| colorbar bottom | |
| """ | |
| fig, axs = plt.subplots(2, 2, layout="constrained") | |
| for ax in axs.flat: | |
| pcm = example_pcolor(ax, fontsize=24) | |
| fig.colorbar(pcm, ax=axs, | |
| use_gridspec=False, pad=0.01, shrink=0.6, | |
| location='bottom') | |
| def test_constrained_layout6(): | |
| """Test constrained_layout for nested gridspecs""" | |
| fig = plt.figure(layout="constrained") | |
| gs = fig.add_gridspec(1, 2, figure=fig) | |
| gsl = gs[0].subgridspec(2, 2) | |
| gsr = gs[1].subgridspec(1, 2) | |
| axsl = [] | |
| for gs in gsl: | |
| ax = fig.add_subplot(gs) | |
| axsl += [ax] | |
| example_plot(ax, fontsize=12) | |
| ax.set_xlabel('x-label\nMultiLine') | |
| axsr = [] | |
| for gs in gsr: | |
| ax = fig.add_subplot(gs) | |
| axsr += [ax] | |
| pcm = example_pcolor(ax, fontsize=12) | |
| fig.colorbar(pcm, ax=axsr, | |
| pad=0.01, shrink=0.99, location='bottom', | |
| ticks=ticker.MaxNLocator(nbins=5)) | |
| def test_identical_subgridspec(): | |
| fig = plt.figure(constrained_layout=True) | |
| GS = fig.add_gridspec(2, 1) | |
| GSA = GS[0].subgridspec(1, 3) | |
| GSB = GS[1].subgridspec(1, 3) | |
| axa = [] | |
| axb = [] | |
| for i in range(3): | |
| axa += [fig.add_subplot(GSA[i])] | |
| axb += [fig.add_subplot(GSB[i])] | |
| fig.draw_without_rendering() | |
| # check first row above second | |
| assert axa[0].get_position().y0 > axb[0].get_position().y1 | |
| def test_constrained_layout7(): | |
| """Test for proper warning if fig not set in GridSpec""" | |
| with pytest.warns( | |
| UserWarning, match=('There are no gridspecs with layoutgrids. ' | |
| 'Possibly did not call parent GridSpec with ' | |
| 'the "figure" keyword')): | |
| fig = plt.figure(layout="constrained") | |
| gs = gridspec.GridSpec(1, 2) | |
| gsl = gridspec.GridSpecFromSubplotSpec(2, 2, gs[0]) | |
| gsr = gridspec.GridSpecFromSubplotSpec(1, 2, gs[1]) | |
| for gs in gsl: | |
| fig.add_subplot(gs) | |
| # need to trigger a draw to get warning | |
| fig.draw_without_rendering() | |
| def test_constrained_layout8(): | |
| """Test for gridspecs that are not completely full""" | |
| fig = plt.figure(figsize=(10, 5), layout="constrained") | |
| gs = gridspec.GridSpec(3, 5, figure=fig) | |
| axs = [] | |
| for j in [0, 1]: | |
| if j == 0: | |
| ilist = [1] | |
| else: | |
| ilist = [0, 4] | |
| for i in ilist: | |
| ax = fig.add_subplot(gs[j, i]) | |
| axs += [ax] | |
| example_pcolor(ax, fontsize=9) | |
| if i > 0: | |
| ax.set_ylabel('') | |
| if j < 1: | |
| ax.set_xlabel('') | |
| ax.set_title('') | |
| ax = fig.add_subplot(gs[2, :]) | |
| axs += [ax] | |
| pcm = example_pcolor(ax, fontsize=9) | |
| fig.colorbar(pcm, ax=axs, pad=0.01, shrink=0.6) | |
| def test_constrained_layout9(): | |
| """Test for handling suptitle and for sharex and sharey""" | |
| fig, axs = plt.subplots(2, 2, layout="constrained", | |
| sharex=False, sharey=False) | |
| for ax in axs.flat: | |
| pcm = example_pcolor(ax, fontsize=24) | |
| ax.set_xlabel('') | |
| ax.set_ylabel('') | |
| ax.set_aspect(2.) | |
| fig.colorbar(pcm, ax=axs, pad=0.01, shrink=0.6) | |
| fig.suptitle('Test Suptitle', fontsize=28) | |
| def test_constrained_layout10(): | |
| """Test for handling legend outside axis""" | |
| fig, axs = plt.subplots(2, 2, layout="constrained") | |
| for ax in axs.flat: | |
| ax.plot(np.arange(12), label='This is a label') | |
| ax.legend(loc='center left', bbox_to_anchor=(0.8, 0.5)) | |
| def test_constrained_layout11(): | |
| """Test for multiple nested gridspecs""" | |
| fig = plt.figure(layout="constrained", figsize=(13, 3)) | |
| gs0 = gridspec.GridSpec(1, 2, figure=fig) | |
| gsl = gridspec.GridSpecFromSubplotSpec(1, 2, gs0[0]) | |
| gsl0 = gridspec.GridSpecFromSubplotSpec(2, 2, gsl[1]) | |
| ax = fig.add_subplot(gs0[1]) | |
| example_plot(ax, fontsize=9) | |
| axs = [] | |
| for gs in gsl0: | |
| ax = fig.add_subplot(gs) | |
| axs += [ax] | |
| pcm = example_pcolor(ax, fontsize=9) | |
| fig.colorbar(pcm, ax=axs, shrink=0.6, aspect=70.) | |
| ax = fig.add_subplot(gsl[0]) | |
| example_plot(ax, fontsize=9) | |
| def test_constrained_layout11rat(): | |
| """Test for multiple nested gridspecs with width_ratios""" | |
| fig = plt.figure(layout="constrained", figsize=(10, 3)) | |
| gs0 = gridspec.GridSpec(1, 2, figure=fig, width_ratios=[6, 1]) | |
| gsl = gridspec.GridSpecFromSubplotSpec(1, 2, gs0[0]) | |
| gsl0 = gridspec.GridSpecFromSubplotSpec(2, 2, gsl[1], height_ratios=[2, 1]) | |
| ax = fig.add_subplot(gs0[1]) | |
| example_plot(ax, fontsize=9) | |
| axs = [] | |
| for gs in gsl0: | |
| ax = fig.add_subplot(gs) | |
| axs += [ax] | |
| pcm = example_pcolor(ax, fontsize=9) | |
| fig.colorbar(pcm, ax=axs, shrink=0.6, aspect=70.) | |
| ax = fig.add_subplot(gsl[0]) | |
| example_plot(ax, fontsize=9) | |
| def test_constrained_layout12(): | |
| """Test that very unbalanced labeling still works.""" | |
| fig = plt.figure(layout="constrained", figsize=(6, 8)) | |
| gs0 = gridspec.GridSpec(6, 2, figure=fig) | |
| ax1 = fig.add_subplot(gs0[:3, 1]) | |
| ax2 = fig.add_subplot(gs0[3:, 1]) | |
| example_plot(ax1, fontsize=18) | |
| example_plot(ax2, fontsize=18) | |
| ax = fig.add_subplot(gs0[0:2, 0]) | |
| example_plot(ax, nodec=True) | |
| ax = fig.add_subplot(gs0[2:4, 0]) | |
| example_plot(ax, nodec=True) | |
| ax = fig.add_subplot(gs0[4:, 0]) | |
| example_plot(ax, nodec=True) | |
| ax.set_xlabel('x-label') | |
| def test_constrained_layout13(): | |
| """Test that padding works.""" | |
| fig, axs = plt.subplots(2, 2, layout="constrained") | |
| for ax in axs.flat: | |
| pcm = example_pcolor(ax, fontsize=12) | |
| fig.colorbar(pcm, ax=ax, shrink=0.6, aspect=20., pad=0.02) | |
| with pytest.raises(TypeError): | |
| fig.get_layout_engine().set(wpad=1, hpad=2) | |
| fig.get_layout_engine().set(w_pad=24./72., h_pad=24./72.) | |
| def test_constrained_layout14(): | |
| """Test that padding works.""" | |
| fig, axs = plt.subplots(2, 2, layout="constrained") | |
| for ax in axs.flat: | |
| pcm = example_pcolor(ax, fontsize=12) | |
| fig.colorbar(pcm, ax=ax, shrink=0.6, aspect=20., pad=0.02) | |
| fig.get_layout_engine().set( | |
| w_pad=3./72., h_pad=3./72., | |
| hspace=0.2, wspace=0.2) | |
| def test_constrained_layout15(): | |
| """Test that rcparams work.""" | |
| mpl.rcParams['figure.constrained_layout.use'] = True | |
| fig, axs = plt.subplots(2, 2) | |
| for ax in axs.flat: | |
| example_plot(ax, fontsize=12) | |
| def test_constrained_layout16(): | |
| """Test ax.set_position.""" | |
| fig, ax = plt.subplots(layout="constrained") | |
| example_plot(ax, fontsize=12) | |
| ax2 = fig.add_axes([0.2, 0.2, 0.4, 0.4]) | |
| def test_constrained_layout17(): | |
| """Test uneven gridspecs""" | |
| fig = plt.figure(layout="constrained") | |
| 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]) | |
| example_plot(ax1) | |
| example_plot(ax2) | |
| example_plot(ax3) | |
| example_plot(ax4) | |
| def test_constrained_layout18(): | |
| """Test twinx""" | |
| fig, ax = plt.subplots(layout="constrained") | |
| ax2 = ax.twinx() | |
| example_plot(ax) | |
| example_plot(ax2, fontsize=24) | |
| fig.draw_without_rendering() | |
| assert all(ax.get_position().extents == ax2.get_position().extents) | |
| def test_constrained_layout19(): | |
| """Test twiny""" | |
| fig, ax = plt.subplots(layout="constrained") | |
| ax2 = ax.twiny() | |
| example_plot(ax) | |
| example_plot(ax2, fontsize=24) | |
| ax2.set_title('') | |
| ax.set_title('') | |
| fig.draw_without_rendering() | |
| assert all(ax.get_position().extents == ax2.get_position().extents) | |
| def test_constrained_layout20(): | |
| """Smoke test cl does not mess up added Axes""" | |
| gx = np.linspace(-5, 5, 4) | |
| img = np.hypot(gx, gx[:, None]) | |
| fig = plt.figure() | |
| ax = fig.add_axes([0, 0, 1, 1]) | |
| mesh = ax.pcolormesh(gx, gx, img[:-1, :-1]) | |
| fig.colorbar(mesh) | |
| def test_constrained_layout21(): | |
| """#11035: repeated calls to suptitle should not alter the layout""" | |
| fig, ax = plt.subplots(layout="constrained") | |
| fig.suptitle("Suptitle0") | |
| fig.draw_without_rendering() | |
| extents0 = np.copy(ax.get_position().extents) | |
| fig.suptitle("Suptitle1") | |
| fig.draw_without_rendering() | |
| extents1 = np.copy(ax.get_position().extents) | |
| np.testing.assert_allclose(extents0, extents1) | |
| def test_constrained_layout22(): | |
| """#11035: suptitle should not be include in CL if manually positioned""" | |
| fig, ax = plt.subplots(layout="constrained") | |
| fig.draw_without_rendering() | |
| extents0 = np.copy(ax.get_position().extents) | |
| fig.suptitle("Suptitle", y=0.5) | |
| fig.draw_without_rendering() | |
| extents1 = np.copy(ax.get_position().extents) | |
| np.testing.assert_allclose(extents0, extents1) | |
| def test_constrained_layout23(): | |
| """ | |
| Comment in #11035: suptitle used to cause an exception when | |
| reusing a figure w/ CL with ``clear=True``. | |
| """ | |
| for i in range(2): | |
| fig = plt.figure(layout="constrained", clear=True, num="123") | |
| gs = fig.add_gridspec(1, 2) | |
| sub = gs[0].subgridspec(2, 2) | |
| fig.suptitle(f"Suptitle{i}") | |
| def test_colorbar_location(): | |
| """ | |
| Test that colorbar handling is as expected for various complicated | |
| cases... | |
| """ | |
| # Remove this line when this test image is regenerated. | |
| plt.rcParams['pcolormesh.snap'] = False | |
| fig, axs = plt.subplots(4, 5, layout="constrained") | |
| for ax in axs.flat: | |
| pcm = example_pcolor(ax) | |
| ax.set_xlabel('') | |
| ax.set_ylabel('') | |
| fig.colorbar(pcm, ax=axs[:, 1], shrink=0.4) | |
| fig.colorbar(pcm, ax=axs[-1, :2], shrink=0.5, location='bottom') | |
| fig.colorbar(pcm, ax=axs[0, 2:], shrink=0.5, location='bottom', pad=0.05) | |
| fig.colorbar(pcm, ax=axs[-2, 3:], shrink=0.5, location='top') | |
| fig.colorbar(pcm, ax=axs[0, 0], shrink=0.5, location='left') | |
| fig.colorbar(pcm, ax=axs[1:3, 2], shrink=0.5, location='right') | |
| def test_hidden_axes(): | |
| # test that if we make an Axes not visible that constrained_layout | |
| # still works. Note the axes still takes space in the layout | |
| # (as does a gridspec slot that is empty) | |
| fig, axs = plt.subplots(2, 2, layout="constrained") | |
| axs[0, 1].set_visible(False) | |
| fig.draw_without_rendering() | |
| extents1 = np.copy(axs[0, 0].get_position().extents) | |
| np.testing.assert_allclose( | |
| extents1, [0.046918, 0.541204, 0.477409, 0.980555], rtol=1e-5) | |
| def test_colorbar_align(): | |
| for location in ['right', 'left', 'top', 'bottom']: | |
| fig, axs = plt.subplots(2, 2, layout="constrained") | |
| cbs = [] | |
| for nn, ax in enumerate(axs.flat): | |
| ax.tick_params(direction='in') | |
| pc = example_pcolor(ax) | |
| cb = fig.colorbar(pc, ax=ax, location=location, shrink=0.6, | |
| pad=0.04) | |
| cbs += [cb] | |
| cb.ax.tick_params(direction='in') | |
| if nn != 1: | |
| cb.ax.xaxis.set_ticks([]) | |
| cb.ax.yaxis.set_ticks([]) | |
| ax.set_xticklabels([]) | |
| ax.set_yticklabels([]) | |
| fig.get_layout_engine().set(w_pad=4 / 72, h_pad=4 / 72, | |
| hspace=0.1, wspace=0.1) | |
| fig.draw_without_rendering() | |
| if location in ['left', 'right']: | |
| np.testing.assert_allclose(cbs[0].ax.get_position().x0, | |
| cbs[2].ax.get_position().x0) | |
| np.testing.assert_allclose(cbs[1].ax.get_position().x0, | |
| cbs[3].ax.get_position().x0) | |
| else: | |
| np.testing.assert_allclose(cbs[0].ax.get_position().y0, | |
| cbs[1].ax.get_position().y0) | |
| np.testing.assert_allclose(cbs[2].ax.get_position().y0, | |
| cbs[3].ax.get_position().y0) | |
| def test_colorbars_no_overlapV(): | |
| fig = plt.figure(figsize=(2, 4), layout="constrained") | |
| axs = fig.subplots(2, 1, sharex=True, sharey=True) | |
| for ax in axs: | |
| ax.yaxis.set_major_formatter(ticker.NullFormatter()) | |
| ax.tick_params(axis='both', direction='in') | |
| im = ax.imshow([[1, 2], [3, 4]]) | |
| fig.colorbar(im, ax=ax, orientation="vertical") | |
| fig.suptitle("foo") | |
| def test_colorbars_no_overlapH(): | |
| fig = plt.figure(figsize=(4, 2), layout="constrained") | |
| fig.suptitle("foo") | |
| axs = fig.subplots(1, 2, sharex=True, sharey=True) | |
| for ax in axs: | |
| ax.yaxis.set_major_formatter(ticker.NullFormatter()) | |
| ax.tick_params(axis='both', direction='in') | |
| im = ax.imshow([[1, 2], [3, 4]]) | |
| fig.colorbar(im, ax=ax, orientation="horizontal") | |
| def test_manually_set_position(): | |
| fig, axs = plt.subplots(1, 2, layout="constrained") | |
| axs[0].set_position([0.2, 0.2, 0.3, 0.3]) | |
| fig.draw_without_rendering() | |
| pp = axs[0].get_position() | |
| np.testing.assert_allclose(pp, [[0.2, 0.2], [0.5, 0.5]]) | |
| fig, axs = plt.subplots(1, 2, layout="constrained") | |
| axs[0].set_position([0.2, 0.2, 0.3, 0.3]) | |
| pc = axs[0].pcolormesh(np.random.rand(20, 20)) | |
| fig.colorbar(pc, ax=axs[0]) | |
| fig.draw_without_rendering() | |
| pp = axs[0].get_position() | |
| np.testing.assert_allclose(pp, [[0.2, 0.2], [0.44, 0.5]]) | |
| def test_bboxtight(): | |
| fig, ax = plt.subplots(layout="constrained") | |
| ax.set_aspect(1.) | |
| def test_bbox(): | |
| fig, ax = plt.subplots(layout="constrained") | |
| ax.set_aspect(1.) | |
| def test_align_labels(): | |
| """ | |
| Tests for a bug in which constrained layout and align_ylabels on | |
| three unevenly sized subplots, one of whose y tick labels include | |
| negative numbers, drives the non-negative subplots' y labels off | |
| the edge of the plot | |
| """ | |
| fig, (ax3, ax1, ax2) = plt.subplots(3, 1, layout="constrained", | |
| figsize=(6.4, 8), | |
| gridspec_kw={"height_ratios": (1, 1, | |
| 0.7)}) | |
| ax1.set_ylim(0, 1) | |
| ax1.set_ylabel("Label") | |
| ax2.set_ylim(-1.5, 1.5) | |
| ax2.set_ylabel("Label") | |
| ax3.set_ylim(0, 1) | |
| ax3.set_ylabel("Label") | |
| fig.align_ylabels(axs=(ax3, ax1, ax2)) | |
| fig.draw_without_rendering() | |
| after_align = [ax1.yaxis.label.get_window_extent(), | |
| ax2.yaxis.label.get_window_extent(), | |
| ax3.yaxis.label.get_window_extent()] | |
| # ensure labels are approximately aligned | |
| np.testing.assert_allclose([after_align[0].x0, after_align[2].x0], | |
| after_align[1].x0, rtol=0, atol=1e-05) | |
| # ensure labels do not go off the edge | |
| assert after_align[0].x0 >= 1 | |
| def test_suplabels(): | |
| fig, ax = plt.subplots(layout="constrained") | |
| fig.draw_without_rendering() | |
| pos0 = ax.get_tightbbox(fig.canvas.get_renderer()) | |
| fig.supxlabel('Boo') | |
| fig.supylabel('Booy') | |
| fig.draw_without_rendering() | |
| pos = ax.get_tightbbox(fig.canvas.get_renderer()) | |
| assert pos.y0 > pos0.y0 + 10.0 | |
| assert pos.x0 > pos0.x0 + 10.0 | |
| fig, ax = plt.subplots(layout="constrained") | |
| fig.draw_without_rendering() | |
| pos0 = ax.get_tightbbox(fig.canvas.get_renderer()) | |
| # check that specifying x (y) doesn't ruin the layout | |
| fig.supxlabel('Boo', x=0.5) | |
| fig.supylabel('Boo', y=0.5) | |
| fig.draw_without_rendering() | |
| pos = ax.get_tightbbox(fig.canvas.get_renderer()) | |
| assert pos.y0 > pos0.y0 + 10.0 | |
| assert pos.x0 > pos0.x0 + 10.0 | |
| def test_gridspec_addressing(): | |
| fig = plt.figure() | |
| gs = fig.add_gridspec(3, 3) | |
| sp = fig.add_subplot(gs[0:, 1:]) | |
| fig.draw_without_rendering() | |
| def test_discouraged_api(): | |
| fig, ax = plt.subplots(constrained_layout=True) | |
| fig.draw_without_rendering() | |
| with pytest.warns(PendingDeprecationWarning, | |
| match="will be deprecated"): | |
| fig, ax = plt.subplots() | |
| fig.set_constrained_layout(True) | |
| fig.draw_without_rendering() | |
| with pytest.warns(PendingDeprecationWarning, | |
| match="will be deprecated"): | |
| fig, ax = plt.subplots() | |
| fig.set_constrained_layout({'w_pad': 0.02, 'h_pad': 0.02}) | |
| fig.draw_without_rendering() | |
| def test_kwargs(): | |
| fig, ax = plt.subplots(constrained_layout={'h_pad': 0.02}) | |
| fig.draw_without_rendering() | |
| def test_rect(): | |
| fig, ax = plt.subplots(layout='constrained') | |
| fig.get_layout_engine().set(rect=[0, 0, 0.5, 0.5]) | |
| fig.draw_without_rendering() | |
| ppos = ax.get_position() | |
| assert ppos.x1 < 0.5 | |
| assert ppos.y1 < 0.5 | |
| fig, ax = plt.subplots(layout='constrained') | |
| fig.get_layout_engine().set(rect=[0.2, 0.2, 0.3, 0.3]) | |
| fig.draw_without_rendering() | |
| ppos = ax.get_position() | |
| assert ppos.x1 < 0.5 | |
| assert ppos.y1 < 0.5 | |
| assert ppos.x0 > 0.2 | |
| assert ppos.y0 > 0.2 | |
| def test_compressed1(): | |
| fig, axs = plt.subplots(3, 2, layout='compressed', | |
| sharex=True, sharey=True) | |
| for ax in axs.flat: | |
| pc = ax.imshow(np.random.randn(20, 20)) | |
| fig.colorbar(pc, ax=axs) | |
| fig.draw_without_rendering() | |
| pos = axs[0, 0].get_position() | |
| np.testing.assert_allclose(pos.x0, 0.2381, atol=1e-2) | |
| pos = axs[0, 1].get_position() | |
| np.testing.assert_allclose(pos.x1, 0.7024, atol=1e-3) | |
| # wider than tall | |
| fig, axs = plt.subplots(2, 3, layout='compressed', | |
| sharex=True, sharey=True, figsize=(5, 4)) | |
| for ax in axs.flat: | |
| pc = ax.imshow(np.random.randn(20, 20)) | |
| fig.colorbar(pc, ax=axs) | |
| fig.draw_without_rendering() | |
| pos = axs[0, 0].get_position() | |
| np.testing.assert_allclose(pos.x0, 0.05653, atol=1e-3) | |
| np.testing.assert_allclose(pos.y1, 0.8603, atol=1e-2) | |
| pos = axs[1, 2].get_position() | |
| np.testing.assert_allclose(pos.x1, 0.8728, atol=1e-3) | |
| np.testing.assert_allclose(pos.y0, 0.1808, atol=1e-2) | |
| def test_compressed_suptitle(): | |
| fig, (ax0, ax1) = plt.subplots( | |
| nrows=2, figsize=(4, 10), layout="compressed", | |
| gridspec_kw={"height_ratios": (1 / 4, 3 / 4), "hspace": 0}) | |
| ax0.axis("equal") | |
| ax0.set_box_aspect(1/3) | |
| ax1.axis("equal") | |
| ax1.set_box_aspect(1) | |
| title = fig.suptitle("Title") | |
| fig.draw_without_rendering() | |
| assert title.get_position()[1] == pytest.approx(0.7491, abs=1e-3) | |
| title = fig.suptitle("Title", y=0.98) | |
| fig.draw_without_rendering() | |
| assert title.get_position()[1] == 0.98 | |
| title = fig.suptitle("Title", in_layout=False) | |
| fig.draw_without_rendering() | |
| assert title.get_position()[1] == 0.98 | |
| def test_set_constrained_layout(arg, state): | |
| fig, ax = plt.subplots(constrained_layout=arg) | |
| assert fig.get_constrained_layout() is state | |
| def test_constrained_toggle(): | |
| fig, ax = plt.subplots() | |
| with pytest.warns(PendingDeprecationWarning): | |
| fig.set_constrained_layout(True) | |
| assert fig.get_constrained_layout() | |
| fig.set_constrained_layout(False) | |
| assert not fig.get_constrained_layout() | |
| fig.set_constrained_layout(True) | |
| assert fig.get_constrained_layout() | |
| def test_layout_leak(): | |
| # Make sure there aren't any cyclic references when using LayoutGrid | |
| # GH #25853 | |
| fig = plt.figure(constrained_layout=True, figsize=(10, 10)) | |
| fig.add_subplot() | |
| fig.draw_without_rendering() | |
| plt.close("all") | |
| del fig | |
| gc.collect() | |
| assert not any(isinstance(obj, mpl._layoutgrid.LayoutGrid) | |
| for obj in gc.get_objects()) | |
| def test_submerged_subfig(): | |
| """ | |
| Test that the submerged margin logic does not get called multiple times | |
| on same axes if it is already in a subfigure | |
| """ | |
| fig = plt.figure(figsize=(4, 5), layout='constrained') | |
| figures = fig.subfigures(3, 1) | |
| axs = [] | |
| for f in figures.flatten(): | |
| gs = f.add_gridspec(2, 2) | |
| for i in range(2): | |
| axs += [f.add_subplot(gs[i, 0])] | |
| axs[-1].plot() | |
| f.add_subplot(gs[:, 1]).plot() | |
| fig.draw_without_rendering() | |
| for ax in axs[1:]: | |
| assert np.allclose(ax.get_position().bounds[-1], | |
| axs[0].get_position().bounds[-1], atol=1e-6) | |