mirror of
https://github.com/kristoferssolo/School.git
synced 2025-10-21 20:10:38 +00:00
171 lines
7.0 KiB
Python
171 lines
7.0 KiB
Python
import matplotlib as mpl
|
|
from matplotlib import _api, cbook
|
|
from matplotlib.axes._axes import Axes
|
|
from matplotlib.gridspec import GridSpec, SubplotSpec
|
|
|
|
|
|
class SubplotBase:
|
|
"""
|
|
Base class for subplots, which are :class:`Axes` instances with
|
|
additional methods to facilitate generating and manipulating a set
|
|
of :class:`Axes` within a figure.
|
|
"""
|
|
|
|
def __init__(self, fig, *args, **kwargs):
|
|
"""
|
|
Parameters
|
|
----------
|
|
fig : `matplotlib.figure.Figure`
|
|
|
|
*args : tuple (*nrows*, *ncols*, *index*) or int
|
|
The array of subplots in the figure has dimensions ``(nrows,
|
|
ncols)``, and *index* is the index of the subplot being created.
|
|
*index* starts at 1 in the upper left corner and increases to the
|
|
right.
|
|
|
|
If *nrows*, *ncols*, and *index* are all single digit numbers, then
|
|
*args* can be passed as a single 3-digit number (e.g. 234 for
|
|
(2, 3, 4)).
|
|
|
|
**kwargs
|
|
Keyword arguments are passed to the Axes (sub)class constructor.
|
|
"""
|
|
# _axes_class is set in the subplot_class_factory
|
|
self._axes_class.__init__(self, fig, [0, 0, 1, 1], **kwargs)
|
|
# This will also update the axes position.
|
|
self.set_subplotspec(SubplotSpec._from_subplot_args(fig, args))
|
|
|
|
@_api.deprecated(
|
|
"3.4", alternative="get_subplotspec",
|
|
addendum="(get_subplotspec returns a SubplotSpec instance.)")
|
|
def get_geometry(self):
|
|
"""Get the subplot geometry, e.g., (2, 2, 3)."""
|
|
rows, cols, num1, num2 = self.get_subplotspec().get_geometry()
|
|
return rows, cols, num1 + 1 # for compatibility
|
|
|
|
@_api.deprecated("3.4", alternative="set_subplotspec")
|
|
def change_geometry(self, numrows, numcols, num):
|
|
"""Change subplot geometry, e.g., from (1, 1, 1) to (2, 2, 3)."""
|
|
self._subplotspec = GridSpec(numrows, numcols,
|
|
figure=self.figure)[num - 1]
|
|
self.update_params()
|
|
self.set_position(self.figbox)
|
|
|
|
def get_subplotspec(self):
|
|
"""Return the `.SubplotSpec` instance associated with the subplot."""
|
|
return self._subplotspec
|
|
|
|
def set_subplotspec(self, subplotspec):
|
|
"""Set the `.SubplotSpec`. instance associated with the subplot."""
|
|
self._subplotspec = subplotspec
|
|
self._set_position(subplotspec.get_position(self.figure))
|
|
|
|
def get_gridspec(self):
|
|
"""Return the `.GridSpec` instance associated with the subplot."""
|
|
return self._subplotspec.get_gridspec()
|
|
|
|
@_api.deprecated(
|
|
"3.4", alternative="get_position()")
|
|
@property
|
|
def figbox(self):
|
|
return self.get_position()
|
|
|
|
@_api.deprecated("3.4", alternative="get_gridspec().nrows")
|
|
@property
|
|
def numRows(self):
|
|
return self.get_gridspec().nrows
|
|
|
|
@_api.deprecated("3.4", alternative="get_gridspec().ncols")
|
|
@property
|
|
def numCols(self):
|
|
return self.get_gridspec().ncols
|
|
|
|
@_api.deprecated("3.4")
|
|
def update_params(self):
|
|
"""Update the subplot position from ``self.figure.subplotpars``."""
|
|
# Now a no-op, as figbox/numRows/numCols are (deprecated) auto-updating
|
|
# properties.
|
|
|
|
@_api.deprecated("3.4", alternative="ax.get_subplotspec().is_first_row()")
|
|
def is_first_row(self):
|
|
return self.get_subplotspec().rowspan.start == 0
|
|
|
|
@_api.deprecated("3.4", alternative="ax.get_subplotspec().is_last_row()")
|
|
def is_last_row(self):
|
|
return self.get_subplotspec().rowspan.stop == self.get_gridspec().nrows
|
|
|
|
@_api.deprecated("3.4", alternative="ax.get_subplotspec().is_first_col()")
|
|
def is_first_col(self):
|
|
return self.get_subplotspec().colspan.start == 0
|
|
|
|
@_api.deprecated("3.4", alternative="ax.get_subplotspec().is_last_col()")
|
|
def is_last_col(self):
|
|
return self.get_subplotspec().colspan.stop == self.get_gridspec().ncols
|
|
|
|
def label_outer(self):
|
|
"""
|
|
Only show "outer" labels and tick labels.
|
|
|
|
x-labels are only kept for subplots on the last row (or first row, if
|
|
labels are on the top side); y-labels only for subplots on the first
|
|
column (or last column, if labels are on the right side).
|
|
"""
|
|
self._label_outer_xaxis(check_patch=False)
|
|
self._label_outer_yaxis(check_patch=False)
|
|
|
|
def _label_outer_xaxis(self, *, check_patch):
|
|
# see documentation in label_outer.
|
|
if check_patch and not isinstance(self.patch, mpl.patches.Rectangle):
|
|
return
|
|
ss = self.get_subplotspec()
|
|
label_position = self.xaxis.get_label_position()
|
|
if not ss.is_first_row(): # Remove top label/ticklabels/offsettext.
|
|
if label_position == "top":
|
|
self.set_xlabel("")
|
|
self.xaxis.set_tick_params(which="both", labeltop=False)
|
|
if self.xaxis.offsetText.get_position()[1] == 1:
|
|
self.xaxis.offsetText.set_visible(False)
|
|
if not ss.is_last_row(): # Remove bottom label/ticklabels/offsettext.
|
|
if label_position == "bottom":
|
|
self.set_xlabel("")
|
|
self.xaxis.set_tick_params(which="both", labelbottom=False)
|
|
if self.xaxis.offsetText.get_position()[1] == 0:
|
|
self.xaxis.offsetText.set_visible(False)
|
|
|
|
def _label_outer_yaxis(self, *, check_patch):
|
|
# see documentation in label_outer.
|
|
if check_patch and not isinstance(self.patch, mpl.patches.Rectangle):
|
|
return
|
|
ss = self.get_subplotspec()
|
|
label_position = self.yaxis.get_label_position()
|
|
if not ss.is_first_col(): # Remove left label/ticklabels/offsettext.
|
|
if label_position == "left":
|
|
self.set_ylabel("")
|
|
self.yaxis.set_tick_params(which="both", labelleft=False)
|
|
if self.yaxis.offsetText.get_position()[0] == 0:
|
|
self.yaxis.offsetText.set_visible(False)
|
|
if not ss.is_last_col(): # Remove right label/ticklabels/offsettext.
|
|
if label_position == "right":
|
|
self.set_ylabel("")
|
|
self.yaxis.set_tick_params(which="both", labelright=False)
|
|
if self.yaxis.offsetText.get_position()[0] == 1:
|
|
self.yaxis.offsetText.set_visible(False)
|
|
|
|
def _make_twin_axes(self, *args, **kwargs):
|
|
"""Make a twinx axes of self. This is used for twinx and twiny."""
|
|
if 'sharex' in kwargs and 'sharey' in kwargs:
|
|
# The following line is added in v2.2 to avoid breaking Seaborn,
|
|
# which currently uses this internal API.
|
|
if kwargs["sharex"] is not self and kwargs["sharey"] is not self:
|
|
raise ValueError("Twinned Axes may share only one axis")
|
|
twin = self.figure.add_subplot(self.get_subplotspec(), *args, **kwargs)
|
|
self.set_adjustable('datalim')
|
|
twin.set_adjustable('datalim')
|
|
self._twinned_axes.join(self, twin)
|
|
return twin
|
|
|
|
|
|
subplot_class_factory = cbook._make_class_factory(
|
|
SubplotBase, "{}Subplot", "_axes_class")
|
|
Subplot = subplot_class_factory(Axes) # Provided for backward compatibility.
|