|
import gc |
|
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 |
|
|
|
|
|
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 |
|
|
|
|
|
@image_comparison(['constrained_layout1.png']) |
|
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) |
|
|
|
|
|
@image_comparison(['constrained_layout2.png']) |
|
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) |
|
|
|
|
|
@image_comparison(['constrained_layout3.png']) |
|
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 |
|
fig.colorbar(pcm, ax=ax, pad=pad) |
|
|
|
|
|
@image_comparison(['constrained_layout4.png']) |
|
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) |
|
|
|
|
|
@image_comparison(['constrained_layout5.png'], tol=0.002) |
|
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') |
|
|
|
|
|
@image_comparison(['constrained_layout6.png'], tol=0.002) |
|
def test_constrained_layout6(): |
|
"""Test constrained_layout for nested gridspecs""" |
|
|
|
plt.rcParams['pcolormesh.snap'] = False |
|
|
|
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() |
|
|
|
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) |
|
|
|
fig.draw_without_rendering() |
|
|
|
|
|
@image_comparison(['constrained_layout8.png']) |
|
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) |
|
|
|
|
|
@image_comparison(['constrained_layout9.png']) |
|
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) |
|
|
|
|
|
@image_comparison(['constrained_layout10.png']) |
|
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)) |
|
|
|
|
|
@image_comparison(['constrained_layout11.png']) |
|
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) |
|
|
|
|
|
@image_comparison(['constrained_layout11rat.png']) |
|
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) |
|
|
|
|
|
@image_comparison(['constrained_layout12.png']) |
|
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') |
|
|
|
|
|
@image_comparison(['constrained_layout13.png'], tol=2.e-2) |
|
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.) |
|
|
|
|
|
@image_comparison(['constrained_layout14.png']) |
|
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) |
|
|
|
|
|
@image_comparison(['constrained_layout15.png']) |
|
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) |
|
|
|
|
|
@image_comparison(['constrained_layout16.png']) |
|
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]) |
|
|
|
|
|
@image_comparison(['constrained_layout17.png']) |
|
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}") |
|
|
|
|
|
@image_comparison(['test_colorbar_location.png'], |
|
remove_text=True, style='mpl20') |
|
def test_colorbar_location(): |
|
""" |
|
Test that colorbar handling is as expected for various complicated |
|
cases... |
|
""" |
|
|
|
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(): |
|
|
|
|
|
|
|
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.045552, 0.543288, 0.47819, 0.982638], 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) |
|
|
|
|
|
@image_comparison(['test_colorbars_no_overlapV.png'], style='mpl20') |
|
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") |
|
|
|
|
|
@image_comparison(['test_colorbars_no_overlapH.png'], style='mpl20') |
|
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]]) |
|
|
|
|
|
@image_comparison(['test_bboxtight.png'], |
|
remove_text=True, style='mpl20', |
|
savefig_kwarg={'bbox_inches': 'tight'}) |
|
def test_bboxtight(): |
|
fig, ax = plt.subplots(layout="constrained") |
|
ax.set_aspect(1.) |
|
|
|
|
|
@image_comparison(['test_bbox.png'], |
|
remove_text=True, style='mpl20', |
|
savefig_kwarg={'bbox_inches': |
|
mtransforms.Bbox([[0.5, 0], [2.5, 2]])}) |
|
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()] |
|
|
|
np.testing.assert_allclose([after_align[0].x0, after_align[2].x0], |
|
after_align[1].x0, rtol=0, atol=1e-05) |
|
|
|
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()) |
|
|
|
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.2344, atol=1e-3) |
|
pos = axs[0, 1].get_position() |
|
np.testing.assert_allclose(pos.x1, 0.7024, atol=1e-3) |
|
|
|
|
|
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.06195, atol=1e-3) |
|
np.testing.assert_allclose(pos.y1, 0.8537, atol=1e-3) |
|
pos = axs[1, 2].get_position() |
|
np.testing.assert_allclose(pos.x1, 0.8618, atol=1e-3) |
|
np.testing.assert_allclose(pos.y0, 0.1934, atol=1e-3) |
|
|
|
|
|
@pytest.mark.parametrize('arg, state', [ |
|
(True, True), |
|
(False, False), |
|
({}, True), |
|
({'rect': None}, True) |
|
]) |
|
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(): |
|
|
|
|
|
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()) |
|
|