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

Skip to content

Commit 2977f37

Browse files
committed
ENH: Add gridspec method to figure, and subplotspecs
1 parent edd053d commit 2977f37

File tree

6 files changed

+227
-76
lines changed

6 files changed

+227
-76
lines changed

doc/users/whats_new.rst

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ revision, see the :ref:`github-stats`.
1515
For a release, add a new section after this, then comment out the include
1616
and toctree below by indenting them. Uncomment them after the release.
1717
18-
.. include:: next_whats_new/README.rst
18+
.. include:: next_whats_new/README.rst
1919
.. toctree::
2020
:glob:
2121
:maxdepth: 1
@@ -190,6 +190,24 @@ specify a number that is close (i.e. ``ax.title.set_position(0.5, 1.01)``)
190190
and the title will not be moved via this algorithm.
191191

192192

193+
New convenience methods for GridSpec
194+
------------------------------------
195+
196+
There are new convenience methods for `.gridspec.GridSpec` and
197+
`.gridspec.GridSpecFromSubplotSpec`. Instead of the former we can
198+
now call `.Figure.add_gridspec` and for the latter `.SubplotSpec.subgridspec`.
199+
200+
.. code-block:: python
201+
202+
import matplotlib.pyplot as plt
203+
204+
fig = plt.figure()
205+
gs0 = fig.add_gridspec(3, 1)
206+
ax1 = fig.add_subplot(gs0[0])
207+
ax2 = fig.add_subplot(gs0[1])
208+
gssub = gs0[2].subgridspec(1, 3)
209+
for i in range(3):
210+
fig.add_subplot(gssub[0, i])
193211
194212
195213

lib/matplotlib/figure.py

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -394,6 +394,9 @@ def __init__(self,
394394
self._align_xlabel_grp = cbook.Grouper()
395395
self._align_ylabel_grp = cbook.Grouper()
396396

397+
# list of child gridspecs for this figure
398+
self._gridspecs = []
399+
397400
# TODO: I'd like to dynamically add the _repr_html_ method
398401
# to the figure in the right context, but then IPython doesn't
399402
# use it, for some reason.
@@ -1480,6 +1483,7 @@ def subplots(self, nrows=1, ncols=1, sharex=False, sharey=False,
14801483
else:
14811484
# this should turn constrained_layout off if we don't want it
14821485
gs = GridSpec(nrows, ncols, figure=None, **gridspec_kw)
1486+
self._gridspecs.append(gs)
14831487

14841488
# Create array to hold all axes.
14851489
axarr = np.empty((nrows, ncols), dtype=object)
@@ -2474,6 +2478,49 @@ def align_labels(self, axs=None):
24742478
self.align_xlabels(axs=axs)
24752479
self.align_ylabels(axs=axs)
24762480

2481+
def add_gridspec(self, nrows, ncols, **kwargs):
2482+
"""
2483+
Return a `.GridSpec` that has this figure as a parent. This allows
2484+
complex layout of axes in the figure.
2485+
2486+
Parameters
2487+
----------
2488+
nrows : int
2489+
Number of rows in grid.
2490+
2491+
ncols : int
2492+
Number or columns in grid.
2493+
2494+
Returns
2495+
-------
2496+
gridspec : `.GridSpec`
2497+
2498+
Other Parameters
2499+
----------------
2500+
*kwargs* are passed to `.GridSpec`.
2501+
2502+
See Also
2503+
--------
2504+
matplotlib.pyplot.subplots
2505+
2506+
Examples
2507+
--------
2508+
Adding a subplot that spans two rows::
2509+
2510+
fig = plt.figure()
2511+
gs = fig.add_gridspec(2, 2)
2512+
ax1 = fig.add_subplot(gs[0, 0])
2513+
ax2 = fig.add_subplot(gs[1, 0])
2514+
# spans two rows:
2515+
ax3 = fig.add_subplot(gs[:, 1])
2516+
2517+
"""
2518+
2519+
_ = kwargs.pop('figure', None) # pop in case user has added this...
2520+
gs = GridSpec(nrows=nrows, ncols=ncols, figure=self, **kwargs)
2521+
self._gridspecs.append(gs)
2522+
return gs
2523+
24772524

24782525
def figaspect(arg):
24792526
"""

lib/matplotlib/gridspec.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -498,3 +498,44 @@ def __eq__(self, other):
498498

499499
def __hash__(self):
500500
return hash((self._gridspec, self.num1, self.num2))
501+
502+
def subgridspec(self, nrows, ncols, **kwargs):
503+
"""
504+
Return a `.GridSpecFromSubplotSpec` that has this subplotspec as
505+
a parent.
506+
507+
Parameters
508+
----------
509+
nrows : int
510+
Number of rows in grid.
511+
512+
ncols : int
513+
Number or columns in grid.
514+
515+
Returns
516+
-------
517+
gridspec : `.GridSpec`
518+
519+
Other Parameters
520+
----------------
521+
**kwargs
522+
All other parameters are passed to `.GridSpec`.
523+
524+
See Also
525+
--------
526+
matplotlib.pyplot.subplots
527+
528+
Examples
529+
--------
530+
Adding three subplots in the space occupied by a single subplot::
531+
532+
fig = plt.figure()
533+
gs0 = fig.add_gridspec(3, 1)
534+
ax1 = fig.add_subplot(gs0[0])
535+
ax2 = fig.add_subplot(gs0[1])
536+
gssub = gs0[2].subgridspec(1, 3)
537+
for i in range(3):
538+
fig.add_subplot(gssub[0, i])
539+
"""
540+
541+
return GridSpecFromSubplotSpec(nrows, ncols, self, **kwargs)

lib/matplotlib/tests/test_constrainedlayout.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -94,9 +94,9 @@ def test_constrained_layout5():
9494
def test_constrained_layout6():
9595
'Test constrained_layout for nested gridspecs'
9696
fig = plt.figure(constrained_layout=True)
97-
gs = gridspec.GridSpec(1, 2, figure=fig)
98-
gsl = gridspec.GridSpecFromSubplotSpec(2, 2, gs[0])
99-
gsr = gridspec.GridSpecFromSubplotSpec(1, 2, gs[1])
97+
gs = fig.add_gridspec(1, 2, figure=fig)
98+
gsl = gs[0].subgridspec(2, 2)
99+
gsr = gs[1].subgridspec(1, 2)
100100
axsl = []
101101
for gs in gsl:
102102
ax = fig.add_subplot(gs)

tutorials/intermediate/constrainedlayout_guide.py

Lines changed: 24 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ def example_plot(ax, fontsize=12, nodec=False):
7878
ax.set_yticklabels('')
7979

8080

81-
fig, ax = plt.subplots()
81+
fig, ax = plt.subplots(constrained_layout=False)
8282
example_plot(ax, fontsize=24)
8383

8484
###############################################################################
@@ -334,8 +334,10 @@ def example_plot(ax, fontsize=12, nodec=False):
334334
# with :func:`~matplotlib.figure.Figure.subplots` or
335335
# :func:`~matplotlib.gridspec.GridSpec` and
336336
# :func:`~matplotlib.figure.Figure.add_subplot`.
337+
#
338+
# Note that in what follows ``constrained_layout=True``
337339

338-
fig = plt.figure(constrained_layout=True)
340+
fig = plt.figure()
339341

340342
gs1 = gridspec.GridSpec(2, 1, figure=fig)
341343
ax1 = fig.add_subplot(gs1[0])
@@ -345,20 +347,21 @@ def example_plot(ax, fontsize=12, nodec=False):
345347
example_plot(ax2)
346348

347349
###############################################################################
348-
# More complicated gridspec layouts are possible.
350+
# More complicated gridspec layouts are possible. Note here we use the
351+
# convenenience functions ``add_gridspec`` and ``subgridspec``
349352

350-
fig = plt.figure(constrained_layout=True)
353+
fig = plt.figure()
351354

352-
gs0 = gridspec.GridSpec(1, 2, figure=fig)
355+
gs0 = fig.add_gridspec(1, 2)
353356

354-
gs1 = gridspec.GridSpecFromSubplotSpec(2, 1, gs0[0])
357+
gs1 = gs0[0].subgridspec(2, 1)
355358
ax1 = fig.add_subplot(gs1[0])
356359
ax2 = fig.add_subplot(gs1[1])
357360

358361
example_plot(ax1)
359362
example_plot(ax2)
360363

361-
gs2 = gridspec.GridSpecFromSubplotSpec(3, 1, gs0[1])
364+
gs2 = gs0[1].subgridspec(3, 1)
362365

363366
for ss in gs2:
364367
ax = fig.add_subplot(ss)
@@ -373,9 +376,9 @@ def example_plot(ax, fontsize=12, nodec=False):
373376
# extent. If we want the top and bottom of the two grids to line up then
374377
# they need to be in the same gridspec:
375378

376-
fig = plt.figure(constrained_layout=True)
379+
fig = plt.figure()
377380

378-
gs0 = gridspec.GridSpec(6, 2, figure=fig)
381+
gs0 = fig.add_gridspec(6, 2)
379382

380383
ax1 = fig.add_subplot(gs0[:3, 0])
381384
ax2 = fig.add_subplot(gs0[3:, 0])
@@ -398,10 +401,10 @@ def example_plot(ax, fontsize=12, nodec=False):
398401

399402

400403
def docomplicated(suptitle=None):
401-
fig = plt.figure(constrained_layout=True)
402-
gs0 = gridspec.GridSpec(1, 2, figure=fig, width_ratios=[1., 2.])
403-
gsl = gridspec.GridSpecFromSubplotSpec(2, 1, gs0[0])
404-
gsr = gridspec.GridSpecFromSubplotSpec(2, 2, gs0[1])
404+
fig = plt.figure()
405+
gs0 = fig.add_gridspec(1, 2, figure=fig, width_ratios=[1., 2.])
406+
gsl = gs0[0].subgridspec(2, 1)
407+
gsr = gs0[1].subgridspec(2, 2)
405408

406409
for gs in gsl:
407410
ax = fig.add_subplot(gs)
@@ -430,7 +433,7 @@ def docomplicated(suptitle=None):
430433
# no effect on it anymore. (Note that constrained_layout still leaves the
431434
# space for the axes that is moved).
432435

433-
fig, axs = plt.subplots(1, 2, constrained_layout=True)
436+
fig, axs = plt.subplots(1, 2)
434437
example_plot(axs[0], fontsize=12)
435438
axs[1].set_position([0.2, 0.2, 0.4, 0.4])
436439

@@ -444,7 +447,7 @@ def docomplicated(suptitle=None):
444447

445448
from matplotlib.transforms import Bbox
446449

447-
fig, axs = plt.subplots(1, 2, constrained_layout=True)
450+
fig, axs = plt.subplots(1, 2)
448451
example_plot(axs[0], fontsize=12)
449452
fig.execute_constrained_layout()
450453
# put into data-space:
@@ -468,7 +471,7 @@ def docomplicated(suptitle=None):
468471
# to yield a nice layout:
469472

470473

471-
fig = plt.figure(constrained_layout=True)
474+
fig = plt.figure()
472475

473476
ax1 = plt.subplot(221)
474477
ax2 = plt.subplot(223)
@@ -481,8 +484,8 @@ def docomplicated(suptitle=None):
481484
###############################################################################
482485
# Of course that layout is possible using a gridspec:
483486

484-
fig = plt.figure(constrained_layout=True)
485-
gs = gridspec.GridSpec(2, 2, figure=fig)
487+
fig = plt.figure()
488+
gs = fig.add_gridspec(2, 2)
486489

487490
ax1 = fig.add_subplot(gs[0, 0])
488491
ax2 = fig.add_subplot(gs[1, 0])
@@ -497,7 +500,7 @@ def docomplicated(suptitle=None):
497500
# :func:`~matplotlib.pyplot.subplot2grid` doesn't work for the same reason:
498501
# each call creates a different parent gridspec.
499502

500-
fig = plt.figure(constrained_layout=True)
503+
fig = plt.figure()
501504

502505
ax1 = plt.subplot2grid((3, 3), (0, 0))
503506
ax2 = plt.subplot2grid((3, 3), (0, 1), colspan=2)
@@ -513,8 +516,8 @@ def docomplicated(suptitle=None):
513516
# The way to make this plot compatible with ``constrained_layout`` is again
514517
# to use ``gridspec`` directly
515518

516-
fig = plt.figure(constrained_layout=True)
517-
gs = gridspec.GridSpec(3, 3, figure=fig)
519+
fig = plt.figure()
520+
gs = fig.add_gridspec(3, 3)
518521

519522
ax1 = fig.add_subplot(gs[0, 0])
520523
ax2 = fig.add_subplot(gs[0, 1:])

0 commit comments

Comments
 (0)