123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738 |
- r"""
- :mod:`~matplotlib.gridspec` contains classes that help to layout multiple
- `~.axes.Axes` in a grid-like pattern within a figure.
- The `GridSpec` specifies the overall grid structure. Individual cells within
- the grid are referenced by `SubplotSpec`\s.
- Often, users need not access this module directly, and can use higher-level
- methods like `~.pyplot.subplots`, `~.pyplot.subplot_mosaic` and
- `~.Figure.subfigures`. See the tutorial :ref:`arranging_axes` for a guide.
- """
- import copy
- import logging
- from numbers import Integral
- import numpy as np
- import matplotlib as mpl
- from matplotlib import _api, _pylab_helpers, _tight_layout
- from matplotlib.transforms import Bbox
- _log = logging.getLogger(__name__)
- class GridSpecBase:
- """
- A base class of GridSpec that specifies the geometry of the grid
- that a subplot will be placed.
- """
- def __init__(self, nrows, ncols, height_ratios=None, width_ratios=None):
- """
- Parameters
- ----------
- nrows, ncols : int
- The number of rows and columns of the grid.
- width_ratios : array-like of length *ncols*, optional
- Defines the relative widths of the columns. Each column gets a
- relative width of ``width_ratios[i] / sum(width_ratios)``.
- If not given, all columns will have the same width.
- height_ratios : array-like of length *nrows*, optional
- Defines the relative heights of the rows. Each row gets a
- relative height of ``height_ratios[i] / sum(height_ratios)``.
- If not given, all rows will have the same height.
- """
- if not isinstance(nrows, Integral) or nrows <= 0:
- raise ValueError(
- f"Number of rows must be a positive integer, not {nrows!r}")
- if not isinstance(ncols, Integral) or ncols <= 0:
- raise ValueError(
- f"Number of columns must be a positive integer, not {ncols!r}")
- self._nrows, self._ncols = nrows, ncols
- self.set_height_ratios(height_ratios)
- self.set_width_ratios(width_ratios)
- def __repr__(self):
- height_arg = (f', height_ratios={self._row_height_ratios!r}'
- if len(set(self._row_height_ratios)) != 1 else '')
- width_arg = (f', width_ratios={self._col_width_ratios!r}'
- if len(set(self._col_width_ratios)) != 1 else '')
- return '{clsname}({nrows}, {ncols}{optionals})'.format(
- clsname=self.__class__.__name__,
- nrows=self._nrows,
- ncols=self._ncols,
- optionals=height_arg + width_arg,
- )
- nrows = property(lambda self: self._nrows,
- doc="The number of rows in the grid.")
- ncols = property(lambda self: self._ncols,
- doc="The number of columns in the grid.")
- def get_geometry(self):
- """
- Return a tuple containing the number of rows and columns in the grid.
- """
- return self._nrows, self._ncols
- def get_subplot_params(self, figure=None):
- # Must be implemented in subclasses
- pass
- def new_subplotspec(self, loc, rowspan=1, colspan=1):
- """
- Create and return a `.SubplotSpec` instance.
- Parameters
- ----------
- loc : (int, int)
- The position of the subplot in the grid as
- ``(row_index, column_index)``.
- rowspan, colspan : int, default: 1
- The number of rows and columns the subplot should span in the grid.
- """
- loc1, loc2 = loc
- subplotspec = self[loc1:loc1+rowspan, loc2:loc2+colspan]
- return subplotspec
- def set_width_ratios(self, width_ratios):
- """
- Set the relative widths of the columns.
- *width_ratios* must be of length *ncols*. Each column gets a relative
- width of ``width_ratios[i] / sum(width_ratios)``.
- """
- if width_ratios is None:
- width_ratios = [1] * self._ncols
- elif len(width_ratios) != self._ncols:
- raise ValueError('Expected the given number of width ratios to '
- 'match the number of columns of the grid')
- self._col_width_ratios = width_ratios
- def get_width_ratios(self):
- """
- Return the width ratios.
- This is *None* if no width ratios have been set explicitly.
- """
- return self._col_width_ratios
- def set_height_ratios(self, height_ratios):
- """
- Set the relative heights of the rows.
- *height_ratios* must be of length *nrows*. Each row gets a relative
- height of ``height_ratios[i] / sum(height_ratios)``.
- """
- if height_ratios is None:
- height_ratios = [1] * self._nrows
- elif len(height_ratios) != self._nrows:
- raise ValueError('Expected the given number of height ratios to '
- 'match the number of rows of the grid')
- self._row_height_ratios = height_ratios
- def get_height_ratios(self):
- """
- Return the height ratios.
- This is *None* if no height ratios have been set explicitly.
- """
- return self._row_height_ratios
- @_api.delete_parameter("3.7", "raw")
- def get_grid_positions(self, fig, raw=False):
- """
- Return the positions of the grid cells in figure coordinates.
- Parameters
- ----------
- fig : `~matplotlib.figure.Figure`
- The figure the grid should be applied to. The subplot parameters
- (margins and spacing between subplots) are taken from *fig*.
- raw : bool, default: False
- If *True*, the subplot parameters of the figure are not taken
- into account. The grid spans the range [0, 1] in both directions
- without margins and there is no space between grid cells. This is
- used for constrained_layout.
- Returns
- -------
- bottoms, tops, lefts, rights : array
- The bottom, top, left, right positions of the grid cells in
- figure coordinates.
- """
- nrows, ncols = self.get_geometry()
- if raw:
- left = 0.
- right = 1.
- bottom = 0.
- top = 1.
- wspace = 0.
- hspace = 0.
- else:
- subplot_params = self.get_subplot_params(fig)
- left = subplot_params.left
- right = subplot_params.right
- bottom = subplot_params.bottom
- top = subplot_params.top
- wspace = subplot_params.wspace
- hspace = subplot_params.hspace
- tot_width = right - left
- tot_height = top - bottom
- # calculate accumulated heights of columns
- cell_h = tot_height / (nrows + hspace*(nrows-1))
- sep_h = hspace * cell_h
- norm = cell_h * nrows / sum(self._row_height_ratios)
- cell_heights = [r * norm for r in self._row_height_ratios]
- sep_heights = [0] + ([sep_h] * (nrows-1))
- cell_hs = np.cumsum(np.column_stack([sep_heights, cell_heights]).flat)
- # calculate accumulated widths of rows
- cell_w = tot_width / (ncols + wspace*(ncols-1))
- sep_w = wspace * cell_w
- norm = cell_w * ncols / sum(self._col_width_ratios)
- cell_widths = [r * norm for r in self._col_width_ratios]
- sep_widths = [0] + ([sep_w] * (ncols-1))
- cell_ws = np.cumsum(np.column_stack([sep_widths, cell_widths]).flat)
- fig_tops, fig_bottoms = (top - cell_hs).reshape((-1, 2)).T
- fig_lefts, fig_rights = (left + cell_ws).reshape((-1, 2)).T
- return fig_bottoms, fig_tops, fig_lefts, fig_rights
- @staticmethod
- def _check_gridspec_exists(figure, nrows, ncols):
- """
- Check if the figure already has a gridspec with these dimensions,
- or create a new one
- """
- for ax in figure.get_axes():
- gs = ax.get_gridspec()
- if gs is not None:
- if hasattr(gs, 'get_topmost_subplotspec'):
- # This is needed for colorbar gridspec layouts.
- # This is probably OK because this whole logic tree
- # is for when the user is doing simple things with the
- # add_subplot command. For complicated layouts
- # like subgridspecs the proper gridspec is passed in...
- gs = gs.get_topmost_subplotspec().get_gridspec()
- if gs.get_geometry() == (nrows, ncols):
- return gs
- # else gridspec not found:
- return GridSpec(nrows, ncols, figure=figure)
- def __getitem__(self, key):
- """Create and return a `.SubplotSpec` instance."""
- nrows, ncols = self.get_geometry()
- def _normalize(key, size, axis): # Includes last index.
- orig_key = key
- if isinstance(key, slice):
- start, stop, _ = key.indices(size)
- if stop > start:
- return start, stop - 1
- raise IndexError("GridSpec slice would result in no space "
- "allocated for subplot")
- else:
- if key < 0:
- key = key + size
- if 0 <= key < size:
- return key, key
- elif axis is not None:
- raise IndexError(f"index {orig_key} is out of bounds for "
- f"axis {axis} with size {size}")
- else: # flat index
- raise IndexError(f"index {orig_key} is out of bounds for "
- f"GridSpec with size {size}")
- if isinstance(key, tuple):
- try:
- k1, k2 = key
- except ValueError as err:
- raise ValueError("Unrecognized subplot spec") from err
- num1, num2 = np.ravel_multi_index(
- [_normalize(k1, nrows, 0), _normalize(k2, ncols, 1)],
- (nrows, ncols))
- else: # Single key
- num1, num2 = _normalize(key, nrows * ncols, None)
- return SubplotSpec(self, num1, num2)
- def subplots(self, *, sharex=False, sharey=False, squeeze=True,
- subplot_kw=None):
- """
- Add all subplots specified by this `GridSpec` to its parent figure.
- See `.Figure.subplots` for detailed documentation.
- """
- figure = self.figure
- if figure is None:
- raise ValueError("GridSpec.subplots() only works for GridSpecs "
- "created with a parent figure")
- if not isinstance(sharex, str):
- sharex = "all" if sharex else "none"
- if not isinstance(sharey, str):
- sharey = "all" if sharey else "none"
- _api.check_in_list(["all", "row", "col", "none", False, True],
- sharex=sharex, sharey=sharey)
- if subplot_kw is None:
- subplot_kw = {}
- # don't mutate kwargs passed by user...
- subplot_kw = subplot_kw.copy()
- # Create array to hold all axes.
- axarr = np.empty((self._nrows, self._ncols), dtype=object)
- for row in range(self._nrows):
- for col in range(self._ncols):
- shared_with = {"none": None, "all": axarr[0, 0],
- "row": axarr[row, 0], "col": axarr[0, col]}
- subplot_kw["sharex"] = shared_with[sharex]
- subplot_kw["sharey"] = shared_with[sharey]
- axarr[row, col] = figure.add_subplot(
- self[row, col], **subplot_kw)
- # turn off redundant tick labeling
- if sharex in ["col", "all"]:
- for ax in axarr.flat:
- ax._label_outer_xaxis(skip_non_rectangular_axes=True)
- if sharey in ["row", "all"]:
- for ax in axarr.flat:
- ax._label_outer_yaxis(skip_non_rectangular_axes=True)
- if squeeze:
- # Discarding unneeded dimensions that equal 1. If we only have one
- # subplot, just return it instead of a 1-element array.
- return axarr.item() if axarr.size == 1 else axarr.squeeze()
- else:
- # Returned axis array will be always 2-d, even if nrows=ncols=1.
- return axarr
- class GridSpec(GridSpecBase):
- """
- A grid layout to place subplots within a figure.
- The location of the grid cells is determined in a similar way to
- `~.figure.SubplotParams` using *left*, *right*, *top*, *bottom*, *wspace*
- and *hspace*.
- Indexing a GridSpec instance returns a `.SubplotSpec`.
- """
- def __init__(self, nrows, ncols, figure=None,
- left=None, bottom=None, right=None, top=None,
- wspace=None, hspace=None,
- width_ratios=None, height_ratios=None):
- """
- Parameters
- ----------
- nrows, ncols : int
- The number of rows and columns of the grid.
- figure : `.Figure`, optional
- Only used for constrained layout to create a proper layoutgrid.
- left, right, top, bottom : float, optional
- Extent of the subplots as a fraction of figure width or height.
- Left cannot be larger than right, and bottom cannot be larger than
- top. If not given, the values will be inferred from a figure or
- rcParams at draw time. See also `GridSpec.get_subplot_params`.
- wspace : float, optional
- The amount of width reserved for space between subplots,
- expressed as a fraction of the average axis width.
- If not given, the values will be inferred from a figure or
- rcParams when necessary. See also `GridSpec.get_subplot_params`.
- hspace : float, optional
- The amount of height reserved for space between subplots,
- expressed as a fraction of the average axis height.
- If not given, the values will be inferred from a figure or
- rcParams when necessary. See also `GridSpec.get_subplot_params`.
- width_ratios : array-like of length *ncols*, optional
- Defines the relative widths of the columns. Each column gets a
- relative width of ``width_ratios[i] / sum(width_ratios)``.
- If not given, all columns will have the same width.
- height_ratios : array-like of length *nrows*, optional
- Defines the relative heights of the rows. Each row gets a
- relative height of ``height_ratios[i] / sum(height_ratios)``.
- If not given, all rows will have the same height.
- """
- self.left = left
- self.bottom = bottom
- self.right = right
- self.top = top
- self.wspace = wspace
- self.hspace = hspace
- self.figure = figure
- super().__init__(nrows, ncols,
- width_ratios=width_ratios,
- height_ratios=height_ratios)
- _AllowedKeys = ["left", "bottom", "right", "top", "wspace", "hspace"]
- def update(self, **kwargs):
- """
- Update the subplot parameters of the grid.
- Parameters that are not explicitly given are not changed. Setting a
- parameter to *None* resets it to :rc:`figure.subplot.*`.
- Parameters
- ----------
- left, right, top, bottom : float or None, optional
- Extent of the subplots as a fraction of figure width or height.
- wspace, hspace : float, optional
- Spacing between the subplots as a fraction of the average subplot
- width / height.
- """
- for k, v in kwargs.items():
- if k in self._AllowedKeys:
- setattr(self, k, v)
- else:
- raise AttributeError(f"{k} is an unknown keyword")
- for figmanager in _pylab_helpers.Gcf.figs.values():
- for ax in figmanager.canvas.figure.axes:
- if ax.get_subplotspec() is not None:
- ss = ax.get_subplotspec().get_topmost_subplotspec()
- if ss.get_gridspec() == self:
- ax._set_position(
- ax.get_subplotspec().get_position(ax.figure))
- def get_subplot_params(self, figure=None):
- """
- Return the `.SubplotParams` for the GridSpec.
- In order of precedence the values are taken from
- - non-*None* attributes of the GridSpec
- - the provided *figure*
- - :rc:`figure.subplot.*`
- Note that the ``figure`` attribute of the GridSpec is always ignored.
- """
- if figure is None:
- kw = {k: mpl.rcParams["figure.subplot."+k]
- for k in self._AllowedKeys}
- subplotpars = mpl.figure.SubplotParams(**kw)
- else:
- subplotpars = copy.copy(figure.subplotpars)
- subplotpars.update(**{k: getattr(self, k) for k in self._AllowedKeys})
- return subplotpars
- def locally_modified_subplot_params(self):
- """
- Return a list of the names of the subplot parameters explicitly set
- in the GridSpec.
- This is a subset of the attributes of `.SubplotParams`.
- """
- return [k for k in self._AllowedKeys if getattr(self, k)]
- def tight_layout(self, figure, renderer=None,
- pad=1.08, h_pad=None, w_pad=None, rect=None):
- """
- Adjust subplot parameters to give specified padding.
- Parameters
- ----------
- figure : `.Figure`
- The figure.
- renderer : `.RendererBase` subclass, optional
- The renderer to be used.
- pad : float
- Padding between the figure edge and the edges of subplots, as a
- fraction of the font-size.
- h_pad, w_pad : float, optional
- Padding (height/width) between edges of adjacent subplots.
- Defaults to *pad*.
- rect : tuple (left, bottom, right, top), default: None
- (left, bottom, right, top) rectangle in normalized figure
- coordinates that the whole subplots area (including labels) will
- fit into. Default (None) is the whole figure.
- """
- if renderer is None:
- renderer = figure._get_renderer()
- kwargs = _tight_layout.get_tight_layout_figure(
- figure, figure.axes,
- _tight_layout.get_subplotspec_list(figure.axes, grid_spec=self),
- renderer, pad=pad, h_pad=h_pad, w_pad=w_pad, rect=rect)
- if kwargs:
- self.update(**kwargs)
- class GridSpecFromSubplotSpec(GridSpecBase):
- """
- GridSpec whose subplot layout parameters are inherited from the
- location specified by a given SubplotSpec.
- """
- def __init__(self, nrows, ncols,
- subplot_spec,
- wspace=None, hspace=None,
- height_ratios=None, width_ratios=None):
- """
- Parameters
- ----------
- nrows, ncols : int
- Number of rows and number of columns of the grid.
- subplot_spec : SubplotSpec
- Spec from which the layout parameters are inherited.
- wspace, hspace : float, optional
- See `GridSpec` for more details. If not specified default values
- (from the figure or rcParams) are used.
- height_ratios : array-like of length *nrows*, optional
- See `GridSpecBase` for details.
- width_ratios : array-like of length *ncols*, optional
- See `GridSpecBase` for details.
- """
- self._wspace = wspace
- self._hspace = hspace
- self._subplot_spec = subplot_spec
- self.figure = self._subplot_spec.get_gridspec().figure
- super().__init__(nrows, ncols,
- width_ratios=width_ratios,
- height_ratios=height_ratios)
- def get_subplot_params(self, figure=None):
- """Return a dictionary of subplot layout parameters."""
- hspace = (self._hspace if self._hspace is not None
- else figure.subplotpars.hspace if figure is not None
- else mpl.rcParams["figure.subplot.hspace"])
- wspace = (self._wspace if self._wspace is not None
- else figure.subplotpars.wspace if figure is not None
- else mpl.rcParams["figure.subplot.wspace"])
- figbox = self._subplot_spec.get_position(figure)
- left, bottom, right, top = figbox.extents
- return mpl.figure.SubplotParams(left=left, right=right,
- bottom=bottom, top=top,
- wspace=wspace, hspace=hspace)
- def get_topmost_subplotspec(self):
- """
- Return the topmost `.SubplotSpec` instance associated with the subplot.
- """
- return self._subplot_spec.get_topmost_subplotspec()
- class SubplotSpec:
- """
- The location of a subplot in a `GridSpec`.
- .. note::
- Likely, you will never instantiate a `SubplotSpec` yourself. Instead,
- you will typically obtain one from a `GridSpec` using item-access.
- Parameters
- ----------
- gridspec : `~matplotlib.gridspec.GridSpec`
- The GridSpec, which the subplot is referencing.
- num1, num2 : int
- The subplot will occupy the *num1*-th cell of the given
- *gridspec*. If *num2* is provided, the subplot will span between
- *num1*-th cell and *num2*-th cell **inclusive**.
- The index starts from 0.
- """
- def __init__(self, gridspec, num1, num2=None):
- self._gridspec = gridspec
- self.num1 = num1
- self.num2 = num2
- def __repr__(self):
- return (f"{self.get_gridspec()}["
- f"{self.rowspan.start}:{self.rowspan.stop}, "
- f"{self.colspan.start}:{self.colspan.stop}]")
- @staticmethod
- def _from_subplot_args(figure, args):
- """
- Construct a `.SubplotSpec` from a parent `.Figure` and either
- - a `.SubplotSpec` -- returned as is;
- - one or three numbers -- a MATLAB-style subplot specifier.
- """
- if len(args) == 1:
- arg, = args
- if isinstance(arg, SubplotSpec):
- return arg
- elif not isinstance(arg, Integral):
- raise ValueError(
- f"Single argument to subplot must be a three-digit "
- f"integer, not {arg!r}")
- try:
- rows, cols, num = map(int, str(arg))
- except ValueError:
- raise ValueError(
- f"Single argument to subplot must be a three-digit "
- f"integer, not {arg!r}") from None
- elif len(args) == 3:
- rows, cols, num = args
- else:
- raise _api.nargs_error("subplot", takes="1 or 3", given=len(args))
- gs = GridSpec._check_gridspec_exists(figure, rows, cols)
- if gs is None:
- gs = GridSpec(rows, cols, figure=figure)
- if isinstance(num, tuple) and len(num) == 2:
- if not all(isinstance(n, Integral) for n in num):
- raise ValueError(
- f"Subplot specifier tuple must contain integers, not {num}"
- )
- i, j = num
- else:
- if not isinstance(num, Integral) or num < 1 or num > rows*cols:
- raise ValueError(
- f"num must be an integer with 1 <= num <= {rows*cols}, "
- f"not {num!r}"
- )
- i = j = num
- return gs[i-1:j]
- # num2 is a property only to handle the case where it is None and someone
- # mutates num1.
- @property
- def num2(self):
- return self.num1 if self._num2 is None else self._num2
- @num2.setter
- def num2(self, value):
- self._num2 = value
- def get_gridspec(self):
- return self._gridspec
- def get_geometry(self):
- """
- Return the subplot geometry as tuple ``(n_rows, n_cols, start, stop)``.
- The indices *start* and *stop* define the range of the subplot within
- the `GridSpec`. *stop* is inclusive (i.e. for a single cell
- ``start == stop``).
- """
- rows, cols = self.get_gridspec().get_geometry()
- return rows, cols, self.num1, self.num2
- @property
- def rowspan(self):
- """The rows spanned by this subplot, as a `range` object."""
- ncols = self.get_gridspec().ncols
- return range(self.num1 // ncols, self.num2 // ncols + 1)
- @property
- def colspan(self):
- """The columns spanned by this subplot, as a `range` object."""
- ncols = self.get_gridspec().ncols
- # We explicitly support num2 referring to a column on num1's *left*, so
- # we must sort the column indices here so that the range makes sense.
- c1, c2 = sorted([self.num1 % ncols, self.num2 % ncols])
- return range(c1, c2 + 1)
- def is_first_row(self):
- return self.rowspan.start == 0
- def is_last_row(self):
- return self.rowspan.stop == self.get_gridspec().nrows
- def is_first_col(self):
- return self.colspan.start == 0
- def is_last_col(self):
- return self.colspan.stop == self.get_gridspec().ncols
- def get_position(self, figure):
- """
- Update the subplot position from ``figure.subplotpars``.
- """
- gridspec = self.get_gridspec()
- nrows, ncols = gridspec.get_geometry()
- rows, cols = np.unravel_index([self.num1, self.num2], (nrows, ncols))
- fig_bottoms, fig_tops, fig_lefts, fig_rights = \
- gridspec.get_grid_positions(figure)
- fig_bottom = fig_bottoms[rows].min()
- fig_top = fig_tops[rows].max()
- fig_left = fig_lefts[cols].min()
- fig_right = fig_rights[cols].max()
- return Bbox.from_extents(fig_left, fig_bottom, fig_right, fig_top)
- def get_topmost_subplotspec(self):
- """
- Return the topmost `SubplotSpec` instance associated with the subplot.
- """
- gridspec = self.get_gridspec()
- if hasattr(gridspec, "get_topmost_subplotspec"):
- return gridspec.get_topmost_subplotspec()
- else:
- return self
- def __eq__(self, other):
- """
- Two SubplotSpecs are considered equal if they refer to the same
- position(s) in the same `GridSpec`.
- """
- # other may not even have the attributes we are checking.
- return ((self._gridspec, self.num1, self.num2)
- == (getattr(other, "_gridspec", object()),
- getattr(other, "num1", object()),
- getattr(other, "num2", object())))
- def __hash__(self):
- return hash((self._gridspec, self.num1, self.num2))
- def subgridspec(self, nrows, ncols, **kwargs):
- """
- Create a GridSpec within this subplot.
- The created `.GridSpecFromSubplotSpec` will have this `SubplotSpec` as
- a parent.
- Parameters
- ----------
- nrows : int
- Number of rows in grid.
- ncols : int
- Number of columns in grid.
- Returns
- -------
- `.GridSpecFromSubplotSpec`
- Other Parameters
- ----------------
- **kwargs
- All other parameters are passed to `.GridSpecFromSubplotSpec`.
- See Also
- --------
- matplotlib.pyplot.subplots
- Examples
- --------
- Adding three subplots in the space occupied by a single subplot::
- fig = plt.figure()
- gs0 = fig.add_gridspec(3, 1)
- ax1 = fig.add_subplot(gs0[0])
- ax2 = fig.add_subplot(gs0[1])
- gssub = gs0[2].subgridspec(1, 3)
- for i in range(3):
- fig.add_subplot(gssub[0, i])
- """
- return GridSpecFromSubplotSpec(nrows, ncols, self, **kwargs)
|