""" :mod:`~matplotlib.gridspec` is a module which specifies the location of the subplot in the figure.
`GridSpec` specifies the geometry of the grid that a subplot will be placed. The number of rows and number of columns of the grid need to be set. Optionally, the subplot layout parameters (e.g., left, right, etc.) can be tuned.
`SubplotSpec` specifies the location of the subplot in the given `GridSpec`.
"""
""" A base class of GridSpec that specifies the geometry of the grid that a subplot will be placed. """
""" The number of rows and number of columns of the grid need to be set. Optionally, the ratio of heights and widths of rows and columns can be specified. """
def __repr__(self): height_arg = (', height_ratios=%r' % self._row_height_ratios if self._row_height_ratios is not None else '') width_arg = (', width_ratios=%r' % self._col_width_ratios if self._col_width_ratios is not None else '') return '{clsname}({nrows}, {ncols}{optionals})'.format( clsname=self.__class__.__name__, nrows=self._nrows, ncols=self._ncols, optionals=height_arg + width_arg, )
'get the geometry of the grid, e.g., 2,3'
pass
""" create and return a SuplotSpec instance. """ loc1, loc2 = loc subplotspec = self[loc1:loc1+rowspan, loc2:loc2+colspan] return subplotspec
raise ValueError('Expected the given number of width ratios to ' 'match the number of columns of the grid')
return self._col_width_ratios
raise ValueError('Expected the given number of height ratios to ' 'match the number of rows of the grid')
return self._row_height_ratios
""" return lists of bottom and top position of rows, left and right positions of columns.
If raw=True, then these are all in units relative to the container with no margins. (used for constrained_layout). """
left = 0. right = 1. bottom = 0. top = 1. wspace = 0. hspace = 0. else:
# calculate accumulated heights of columns else:
# calculate accumulated widths of rows norm = cell_w * ncols / sum(self._col_width_ratios) cell_widths = [r * norm for r in self._col_width_ratios] else:
"""Create and return a SuplotSpec instance. """
start, stop, _ = key.indices(size) if stop > start: return start, stop - 1 else: key += size raise IndexError("invalid index")
except ValueError: raise ValueError("unrecognized subplot spec") [_normalize(k1, nrows), _normalize(k2, ncols)], (nrows, ncols)) else: # Single key
""" A class that specifies the geometry of the grid that a subplot will be placed. The location of grid is determined by similar way as the SubplotParams. """
left=None, bottom=None, right=None, top=None, wspace=None, hspace=None, width_ratios=None, height_ratios=None): """ The number of rows and number of columns of the grid need to be set. Optionally, the subplot layout parameters (e.g., left, right, etc.) can be tuned.
Parameters ---------- nrows : int Number of rows in grid.
ncols : int Number or columns in grid.
figure : ~.figure.Figure, optional
left, right, top, bottom : float 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.
wspace : float The amount of width reserved for space between subplots, expressed as a fraction of the average axis width.
hspace : float The amount of height reserved for space between subplots, expressed as a fraction of the average axis height.
Notes ----- See `~.figure.SubplotParams` for descriptions of the layout parameters. """
width_ratios=width_ratios, height_ratios=height_ratios)
else: self.figure.init_layoutbox() self._layoutbox = layoutbox.LayoutBox( parent=self.figure._layoutbox, name='gridspec' + layoutbox.seq_id(), artist=self) # by default the layoutbox for a gridsepc will fill a figure. # but this can change below if the gridspec is created from a # subplotspec. (GridSpecFromSubplotSpec)
state = self.__dict__ try: state.pop('_layoutbox') except KeyError: pass return state
self.__dict__ = state # layoutboxes don't survive pickling... self._layoutbox = None
""" Update the current values. If any kwarg is None, default to the current value, if set, otherwise to rc. """
for k, v in kwargs.items(): if k in self._AllowedKeys: setattr(self, k, v) else: raise AttributeError("%s is unknown keyword" % (k,))
for figmanager in _pylab_helpers.Gcf.figs.values(): for ax in figmanager.canvas.figure.axes: # copied from Figure.subplots_adjust if not isinstance(ax, mpl.axes.SubplotBase): # Check if sharing a subplots axis if isinstance(ax._sharex, mpl.axes.SubplotBase): if ax._sharex.get_subplotspec().get_gridspec() == self: ax._sharex.update_params() ax._set_position(ax._sharex.figbox) elif isinstance(ax._sharey, mpl.axes.SubplotBase): if ax._sharey.get_subplotspec().get_gridspec() == self: ax._sharey.update_params() ax._set_position(ax._sharey.figbox) else: ss = ax.get_subplotspec().get_topmost_subplotspec() if ss.get_gridspec() == self: ax.update_params() ax._set_position(ax.figbox)
""" Return a dictionary of subplot layout parameters. The default parameters are from rcParams unless a figure attribute is set. """ cbook.warn_deprecated("2.2", "fig", obj_type="keyword argument", alternative="figure") figure = fig
kw = {k: rcParams["figure.subplot."+k] for k in self._AllowedKeys} subplotpars = mpl.figure.SubplotParams(**kw) else:
return [k for k in self._AllowedKeys if getattr(self, k)]
pad=1.08, h_pad=None, w_pad=None, rect=None): """ Adjust subplot parameters to give specified padding.
Parameters ----------
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_inches``. rect : tuple of 4 floats, optional (left, bottom, right, top) rectangle in normalized figure coordinates that the whole subplots area (including labels) will fit into. Default is (0, 0, 1, 1). """
subplotspec_list = tight_layout.get_subplotspec_list( figure.axes, grid_spec=self) if None in subplotspec_list: warnings.warn("This figure includes Axes that are not compatible " "with tight_layout, so results might be incorrect.")
if renderer is None: renderer = tight_layout.get_renderer(figure)
kwargs = tight_layout.get_tight_layout_figure( figure, figure.axes, subplotspec_list, renderer, pad=pad, h_pad=h_pad, w_pad=w_pad, rect=rect) if kwargs: self.update(**kwargs)
""" GridSpec whose subplot layout parameters are inherited from the location specified by a given SubplotSpec. """ subplot_spec, wspace=None, hspace=None, height_ratios=None, width_ratios=None): """ The number of rows and number of columns of the grid need to be set. An instance of SubplotSpec is also needed to be set from which the layout parameters will be inherited. The wspace and hspace of the layout can be optionally specified or the default values (from the figure or rcParams) will be used. """ self._wspace = wspace self._hspace = hspace self._subplot_spec = subplot_spec GridSpecBase.__init__(self, nrows, ncols, width_ratios=width_ratios, height_ratios=height_ratios) # do the layoutboxes subspeclb = subplot_spec._layoutbox if subspeclb is None: self._layoutbox = None else: # OK, this is needed to divide the figure. self._layoutbox = subspeclb.layout_from_subplotspec( subplot_spec, name=subspeclb.name + '.gridspec' + layoutbox.seq_id(), artist=self)
"""Return a dictionary of subplot layout parameters. """ if fig is not None: cbook.warn_deprecated("2.2", "fig", obj_type="keyword argument", alternative="figure") if figure is None: figure = fig
hspace = (self._hspace if self._hspace is not None else figure.subplotpars.hspace if figure is not None else rcParams["figure.subplot.hspace"]) wspace = (self._wspace if self._wspace is not None else figure.subplotpars.wspace if figure is not None else 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)
"""Get the topmost SubplotSpec instance associated with the subplot.""" return self._subplot_spec.get_topmost_subplotspec()
"""Specifies the location of the subplot in the given `GridSpec`. """
""" 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.
The index starts from 0. """ glb = gridspec._layoutbox # So note that here we don't assign any layout yet, # just make the layoutbox that will conatin all items # associated w/ this axis. This can include other axes like # a colorbar or a legend. self._layoutbox = layoutbox.LayoutBox( parent=glb, name=glb.name + '.ss' + layoutbox.seq_id(), artist=self) else:
state = self.__dict__ try: state.pop('_layoutbox') except KeyError: pass return state
self.__dict__ = state # layoutboxes don't survive pickling... self._layoutbox = None
""" Get the subplot geometry (``n_rows, n_cols, start, stop``).
start and stop are the index of the start and stop of the subplot. """ rows, cols = self.get_gridspec().get_geometry() return rows, cols, self.num1, self.num2
""" Get the subplot row and column numbers: (``n_rows, n_cols, row_start, row_stop, col_start, col_stop``) """ gridspec = self.get_gridspec() nrows, ncols = gridspec.get_geometry() row_start, col_start = divmod(self.num1, ncols) if self.num2 is not None: row_stop, col_stop = divmod(self.num2, ncols) else: row_stop = row_start col_stop = col_start return nrows, ncols, row_start, row_stop, col_start, col_stop
"""Update the subplot position from ``figure.subplotpars``. """ [self.num1] if self.num2 is None else [self.num1, self.num2], (nrows, ncols)) gridspec.get_grid_positions(figure)
else: return figbox
'get 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
# other may not even have the attributes we are checking. == (getattr(other, "_gridspec", object()), getattr(other, "num1", object()), getattr(other, "num2", object())))
""" Return a `.GridSpecFromSubplotSpec` that has this subplotspec as a parent.
Parameters ---------- nrows : int Number of rows in grid.
ncols : int Number or columns in grid.
Returns ------- gridspec : `.GridSpec`
Other Parameters ---------------- **kwargs All other parameters are passed to `.GridSpec`.
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) |