aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/python/matplotlib/py3/mpl_toolkits/axes_grid1
diff options
context:
space:
mode:
authormaxim-yurchuk <maxim-yurchuk@yandex-team.com>2025-02-11 13:26:52 +0300
committermaxim-yurchuk <maxim-yurchuk@yandex-team.com>2025-02-11 13:57:59 +0300
commitf895bba65827952ed934b2b46f9a45e30a191fd2 (patch)
tree03260c906d9ec41cdc03e2a496b15d407459cec0 /contrib/python/matplotlib/py3/mpl_toolkits/axes_grid1
parent5f7060466f7b9707818c2091e1a25c14f33c3474 (diff)
downloadydb-f895bba65827952ed934b2b46f9a45e30a191fd2.tar.gz
Remove deps on pandas
<https://github.com/ydb-platform/ydb/pull/14418> <https://github.com/ydb-platform/ydb/pull/14419> \-- аналогичные правки в gh Хочу залить в обход синка, чтобы посмотреть удалится ли pandas в нашей gh репе через piglet commit_hash:abca127aa37d4dbb94b07e1e18cdb8eb5b711860
Diffstat (limited to 'contrib/python/matplotlib/py3/mpl_toolkits/axes_grid1')
-rw-r--r--contrib/python/matplotlib/py3/mpl_toolkits/axes_grid1/__init__.py10
-rw-r--r--contrib/python/matplotlib/py3/mpl_toolkits/axes_grid1/anchored_artists.py462
-rw-r--r--contrib/python/matplotlib/py3/mpl_toolkits/axes_grid1/axes_divider.py694
-rw-r--r--contrib/python/matplotlib/py3/mpl_toolkits/axes_grid1/axes_grid.py550
-rw-r--r--contrib/python/matplotlib/py3/mpl_toolkits/axes_grid1/axes_rgb.py157
-rw-r--r--contrib/python/matplotlib/py3/mpl_toolkits/axes_grid1/axes_size.py248
-rw-r--r--contrib/python/matplotlib/py3/mpl_toolkits/axes_grid1/inset_locator.py561
-rw-r--r--contrib/python/matplotlib/py3/mpl_toolkits/axes_grid1/mpl_axes.py128
-rw-r--r--contrib/python/matplotlib/py3/mpl_toolkits/axes_grid1/parasite_axes.py257
9 files changed, 0 insertions, 3067 deletions
diff --git a/contrib/python/matplotlib/py3/mpl_toolkits/axes_grid1/__init__.py b/contrib/python/matplotlib/py3/mpl_toolkits/axes_grid1/__init__.py
deleted file mode 100644
index c55302485e3..00000000000
--- a/contrib/python/matplotlib/py3/mpl_toolkits/axes_grid1/__init__.py
+++ /dev/null
@@ -1,10 +0,0 @@
-from . import axes_size as Size
-from .axes_divider import Divider, SubplotDivider, make_axes_locatable
-from .axes_grid import AxesGrid, Grid, ImageGrid
-
-from .parasite_axes import host_subplot, host_axes
-
-__all__ = ["Size",
- "Divider", "SubplotDivider", "make_axes_locatable",
- "AxesGrid", "Grid", "ImageGrid",
- "host_subplot", "host_axes"]
diff --git a/contrib/python/matplotlib/py3/mpl_toolkits/axes_grid1/anchored_artists.py b/contrib/python/matplotlib/py3/mpl_toolkits/axes_grid1/anchored_artists.py
deleted file mode 100644
index 1238310b462..00000000000
--- a/contrib/python/matplotlib/py3/mpl_toolkits/axes_grid1/anchored_artists.py
+++ /dev/null
@@ -1,462 +0,0 @@
-from matplotlib import _api, transforms
-from matplotlib.offsetbox import (AnchoredOffsetbox, AuxTransformBox,
- DrawingArea, TextArea, VPacker)
-from matplotlib.patches import (Rectangle, Ellipse, ArrowStyle,
- FancyArrowPatch, PathPatch)
-from matplotlib.text import TextPath
-
-__all__ = ['AnchoredDrawingArea', 'AnchoredAuxTransformBox',
- 'AnchoredEllipse', 'AnchoredSizeBar', 'AnchoredDirectionArrows']
-
-
-class AnchoredDrawingArea(AnchoredOffsetbox):
- def __init__(self, width, height, xdescent, ydescent,
- loc, pad=0.4, borderpad=0.5, prop=None, frameon=True,
- **kwargs):
- """
- An anchored container with a fixed size and fillable `.DrawingArea`.
-
- Artists added to the *drawing_area* will have their coordinates
- interpreted as pixels. Any transformations set on the artists will be
- overridden.
-
- Parameters
- ----------
- width, height : float
- Width and height of the container, in pixels.
- xdescent, ydescent : float
- Descent of the container in the x- and y- direction, in pixels.
- loc : str
- Location of this artist. Valid locations are
- 'upper left', 'upper center', 'upper right',
- 'center left', 'center', 'center right',
- 'lower left', 'lower center', 'lower right'.
- For backward compatibility, numeric values are accepted as well.
- See the parameter *loc* of `.Legend` for details.
- pad : float, default: 0.4
- Padding around the child objects, in fraction of the font size.
- borderpad : float, default: 0.5
- Border padding, in fraction of the font size.
- prop : `~matplotlib.font_manager.FontProperties`, optional
- Font property used as a reference for paddings.
- frameon : bool, default: True
- If True, draw a box around this artist.
- **kwargs
- Keyword arguments forwarded to `.AnchoredOffsetbox`.
-
- Attributes
- ----------
- drawing_area : `~matplotlib.offsetbox.DrawingArea`
- A container for artists to display.
-
- Examples
- --------
- To display blue and red circles of different sizes in the upper right
- of an Axes *ax*:
-
- >>> ada = AnchoredDrawingArea(20, 20, 0, 0,
- ... loc='upper right', frameon=False)
- >>> ada.drawing_area.add_artist(Circle((10, 10), 10, fc="b"))
- >>> ada.drawing_area.add_artist(Circle((30, 10), 5, fc="r"))
- >>> ax.add_artist(ada)
- """
- self.da = DrawingArea(width, height, xdescent, ydescent)
- self.drawing_area = self.da
-
- super().__init__(
- loc, pad=pad, borderpad=borderpad, child=self.da, prop=None,
- frameon=frameon, **kwargs
- )
-
-
-class AnchoredAuxTransformBox(AnchoredOffsetbox):
- def __init__(self, transform, loc,
- pad=0.4, borderpad=0.5, prop=None, frameon=True, **kwargs):
- """
- An anchored container with transformed coordinates.
-
- Artists added to the *drawing_area* are scaled according to the
- coordinates of the transformation used. The dimensions of this artist
- will scale to contain the artists added.
-
- Parameters
- ----------
- transform : `~matplotlib.transforms.Transform`
- The transformation object for the coordinate system in use, i.e.,
- :attr:`matplotlib.axes.Axes.transData`.
- loc : str
- Location of this artist. Valid locations are
- 'upper left', 'upper center', 'upper right',
- 'center left', 'center', 'center right',
- 'lower left', 'lower center', 'lower right'.
- For backward compatibility, numeric values are accepted as well.
- See the parameter *loc* of `.Legend` for details.
- pad : float, default: 0.4
- Padding around the child objects, in fraction of the font size.
- borderpad : float, default: 0.5
- Border padding, in fraction of the font size.
- prop : `~matplotlib.font_manager.FontProperties`, optional
- Font property used as a reference for paddings.
- frameon : bool, default: True
- If True, draw a box around this artist.
- **kwargs
- Keyword arguments forwarded to `.AnchoredOffsetbox`.
-
- Attributes
- ----------
- drawing_area : `~matplotlib.offsetbox.AuxTransformBox`
- A container for artists to display.
-
- Examples
- --------
- To display an ellipse in the upper left, with a width of 0.1 and
- height of 0.4 in data coordinates:
-
- >>> box = AnchoredAuxTransformBox(ax.transData, loc='upper left')
- >>> el = Ellipse((0, 0), width=0.1, height=0.4, angle=30)
- >>> box.drawing_area.add_artist(el)
- >>> ax.add_artist(box)
- """
- self.drawing_area = AuxTransformBox(transform)
-
- super().__init__(loc, pad=pad, borderpad=borderpad,
- child=self.drawing_area, prop=prop, frameon=frameon,
- **kwargs)
-
-
-@_api.deprecated("3.8")
-class AnchoredEllipse(AnchoredOffsetbox):
- def __init__(self, transform, width, height, angle, loc,
- pad=0.1, borderpad=0.1, prop=None, frameon=True, **kwargs):
- """
- Draw an anchored ellipse of a given size.
-
- Parameters
- ----------
- transform : `~matplotlib.transforms.Transform`
- The transformation object for the coordinate system in use, i.e.,
- :attr:`matplotlib.axes.Axes.transData`.
- width, height : float
- Width and height of the ellipse, given in coordinates of
- *transform*.
- angle : float
- Rotation of the ellipse, in degrees, anti-clockwise.
- loc : str
- Location of the ellipse. Valid locations are
- 'upper left', 'upper center', 'upper right',
- 'center left', 'center', 'center right',
- 'lower left', 'lower center', 'lower right'.
- For backward compatibility, numeric values are accepted as well.
- See the parameter *loc* of `.Legend` for details.
- pad : float, default: 0.1
- Padding around the ellipse, in fraction of the font size.
- borderpad : float, default: 0.1
- Border padding, in fraction of the font size.
- frameon : bool, default: True
- If True, draw a box around the ellipse.
- prop : `~matplotlib.font_manager.FontProperties`, optional
- Font property used as a reference for paddings.
- **kwargs
- Keyword arguments forwarded to `.AnchoredOffsetbox`.
-
- Attributes
- ----------
- ellipse : `~matplotlib.patches.Ellipse`
- Ellipse patch drawn.
- """
- self._box = AuxTransformBox(transform)
- self.ellipse = Ellipse((0, 0), width, height, angle=angle)
- self._box.add_artist(self.ellipse)
-
- super().__init__(loc, pad=pad, borderpad=borderpad, child=self._box,
- prop=prop, frameon=frameon, **kwargs)
-
-
-class AnchoredSizeBar(AnchoredOffsetbox):
- def __init__(self, transform, size, label, loc,
- pad=0.1, borderpad=0.1, sep=2,
- frameon=True, size_vertical=0, color='black',
- label_top=False, fontproperties=None, fill_bar=None,
- **kwargs):
- """
- Draw a horizontal scale bar with a center-aligned label underneath.
-
- Parameters
- ----------
- transform : `~matplotlib.transforms.Transform`
- The transformation object for the coordinate system in use, i.e.,
- :attr:`matplotlib.axes.Axes.transData`.
- size : float
- Horizontal length of the size bar, given in coordinates of
- *transform*.
- label : str
- Label to display.
- loc : str
- Location of the size bar. Valid locations are
- 'upper left', 'upper center', 'upper right',
- 'center left', 'center', 'center right',
- 'lower left', 'lower center', 'lower right'.
- For backward compatibility, numeric values are accepted as well.
- See the parameter *loc* of `.Legend` for details.
- pad : float, default: 0.1
- Padding around the label and size bar, in fraction of the font
- size.
- borderpad : float, default: 0.1
- Border padding, in fraction of the font size.
- sep : float, default: 2
- Separation between the label and the size bar, in points.
- frameon : bool, default: True
- If True, draw a box around the horizontal bar and label.
- size_vertical : float, default: 0
- Vertical length of the size bar, given in coordinates of
- *transform*.
- color : str, default: 'black'
- Color for the size bar and label.
- label_top : bool, default: False
- If True, the label will be over the size bar.
- fontproperties : `~matplotlib.font_manager.FontProperties`, optional
- Font properties for the label text.
- fill_bar : bool, optional
- If True and if *size_vertical* is nonzero, the size bar will
- be filled in with the color specified by the size bar.
- Defaults to True if *size_vertical* is greater than
- zero and False otherwise.
- **kwargs
- Keyword arguments forwarded to `.AnchoredOffsetbox`.
-
- Attributes
- ----------
- size_bar : `~matplotlib.offsetbox.AuxTransformBox`
- Container for the size bar.
- txt_label : `~matplotlib.offsetbox.TextArea`
- Container for the label of the size bar.
-
- Notes
- -----
- If *prop* is passed as a keyword argument, but *fontproperties* is
- not, then *prop* is assumed to be the intended *fontproperties*.
- Using both *prop* and *fontproperties* is not supported.
-
- Examples
- --------
- >>> import matplotlib.pyplot as plt
- >>> import numpy as np
- >>> from mpl_toolkits.axes_grid1.anchored_artists import (
- ... AnchoredSizeBar)
- >>> fig, ax = plt.subplots()
- >>> ax.imshow(np.random.random((10, 10)))
- >>> bar = AnchoredSizeBar(ax.transData, 3, '3 data units', 4)
- >>> ax.add_artist(bar)
- >>> fig.show()
-
- Using all the optional parameters
-
- >>> import matplotlib.font_manager as fm
- >>> fontprops = fm.FontProperties(size=14, family='monospace')
- >>> bar = AnchoredSizeBar(ax.transData, 3, '3 units', 4, pad=0.5,
- ... sep=5, borderpad=0.5, frameon=False,
- ... size_vertical=0.5, color='white',
- ... fontproperties=fontprops)
- """
- if fill_bar is None:
- fill_bar = size_vertical > 0
-
- self.size_bar = AuxTransformBox(transform)
- self.size_bar.add_artist(Rectangle((0, 0), size, size_vertical,
- fill=fill_bar, facecolor=color,
- edgecolor=color))
-
- if fontproperties is None and 'prop' in kwargs:
- fontproperties = kwargs.pop('prop')
-
- if fontproperties is None:
- textprops = {'color': color}
- else:
- textprops = {'color': color, 'fontproperties': fontproperties}
-
- self.txt_label = TextArea(label, textprops=textprops)
-
- if label_top:
- _box_children = [self.txt_label, self.size_bar]
- else:
- _box_children = [self.size_bar, self.txt_label]
-
- self._box = VPacker(children=_box_children,
- align="center",
- pad=0, sep=sep)
-
- super().__init__(loc, pad=pad, borderpad=borderpad, child=self._box,
- prop=fontproperties, frameon=frameon, **kwargs)
-
-
-class AnchoredDirectionArrows(AnchoredOffsetbox):
- def __init__(self, transform, label_x, label_y, length=0.15,
- fontsize=0.08, loc='upper left', angle=0, aspect_ratio=1,
- pad=0.4, borderpad=0.4, frameon=False, color='w', alpha=1,
- sep_x=0.01, sep_y=0, fontproperties=None, back_length=0.15,
- head_width=10, head_length=15, tail_width=2,
- text_props=None, arrow_props=None,
- **kwargs):
- """
- Draw two perpendicular arrows to indicate directions.
-
- Parameters
- ----------
- transform : `~matplotlib.transforms.Transform`
- The transformation object for the coordinate system in use, i.e.,
- :attr:`matplotlib.axes.Axes.transAxes`.
- label_x, label_y : str
- Label text for the x and y arrows
- length : float, default: 0.15
- Length of the arrow, given in coordinates of *transform*.
- fontsize : float, default: 0.08
- Size of label strings, given in coordinates of *transform*.
- loc : str, default: 'upper left'
- Location of the arrow. Valid locations are
- 'upper left', 'upper center', 'upper right',
- 'center left', 'center', 'center right',
- 'lower left', 'lower center', 'lower right'.
- For backward compatibility, numeric values are accepted as well.
- See the parameter *loc* of `.Legend` for details.
- angle : float, default: 0
- The angle of the arrows in degrees.
- aspect_ratio : float, default: 1
- The ratio of the length of arrow_x and arrow_y.
- Negative numbers can be used to change the direction.
- pad : float, default: 0.4
- Padding around the labels and arrows, in fraction of the font size.
- borderpad : float, default: 0.4
- Border padding, in fraction of the font size.
- frameon : bool, default: False
- If True, draw a box around the arrows and labels.
- color : str, default: 'white'
- Color for the arrows and labels.
- alpha : float, default: 1
- Alpha values of the arrows and labels
- sep_x, sep_y : float, default: 0.01 and 0 respectively
- Separation between the arrows and labels in coordinates of
- *transform*.
- fontproperties : `~matplotlib.font_manager.FontProperties`, optional
- Font properties for the label text.
- back_length : float, default: 0.15
- Fraction of the arrow behind the arrow crossing.
- head_width : float, default: 10
- Width of arrow head, sent to `.ArrowStyle`.
- head_length : float, default: 15
- Length of arrow head, sent to `.ArrowStyle`.
- tail_width : float, default: 2
- Width of arrow tail, sent to `.ArrowStyle`.
- text_props, arrow_props : dict
- Properties of the text and arrows, passed to `.TextPath` and
- `.FancyArrowPatch`.
- **kwargs
- Keyword arguments forwarded to `.AnchoredOffsetbox`.
-
- Attributes
- ----------
- arrow_x, arrow_y : `~matplotlib.patches.FancyArrowPatch`
- Arrow x and y
- text_path_x, text_path_y : `~matplotlib.text.TextPath`
- Path for arrow labels
- p_x, p_y : `~matplotlib.patches.PathPatch`
- Patch for arrow labels
- box : `~matplotlib.offsetbox.AuxTransformBox`
- Container for the arrows and labels.
-
- Notes
- -----
- If *prop* is passed as a keyword argument, but *fontproperties* is
- not, then *prop* is assumed to be the intended *fontproperties*.
- Using both *prop* and *fontproperties* is not supported.
-
- Examples
- --------
- >>> import matplotlib.pyplot as plt
- >>> import numpy as np
- >>> from mpl_toolkits.axes_grid1.anchored_artists import (
- ... AnchoredDirectionArrows)
- >>> fig, ax = plt.subplots()
- >>> ax.imshow(np.random.random((10, 10)))
- >>> arrows = AnchoredDirectionArrows(ax.transAxes, '111', '110')
- >>> ax.add_artist(arrows)
- >>> fig.show()
-
- Using several of the optional parameters, creating downward pointing
- arrow and high contrast text labels.
-
- >>> import matplotlib.font_manager as fm
- >>> fontprops = fm.FontProperties(family='monospace')
- >>> arrows = AnchoredDirectionArrows(ax.transAxes, 'East', 'South',
- ... loc='lower left', color='k',
- ... aspect_ratio=-1, sep_x=0.02,
- ... sep_y=-0.01,
- ... text_props={'ec':'w', 'fc':'k'},
- ... fontproperties=fontprops)
- """
- if arrow_props is None:
- arrow_props = {}
-
- if text_props is None:
- text_props = {}
-
- arrowstyle = ArrowStyle("Simple",
- head_width=head_width,
- head_length=head_length,
- tail_width=tail_width)
-
- if fontproperties is None and 'prop' in kwargs:
- fontproperties = kwargs.pop('prop')
-
- if 'color' not in arrow_props:
- arrow_props['color'] = color
-
- if 'alpha' not in arrow_props:
- arrow_props['alpha'] = alpha
-
- if 'color' not in text_props:
- text_props['color'] = color
-
- if 'alpha' not in text_props:
- text_props['alpha'] = alpha
-
- t_start = transform
- t_end = t_start + transforms.Affine2D().rotate_deg(angle)
-
- self.box = AuxTransformBox(t_end)
-
- length_x = length
- length_y = length*aspect_ratio
-
- self.arrow_x = FancyArrowPatch(
- (0, back_length*length_y),
- (length_x, back_length*length_y),
- arrowstyle=arrowstyle,
- shrinkA=0.0,
- shrinkB=0.0,
- **arrow_props)
-
- self.arrow_y = FancyArrowPatch(
- (back_length*length_x, 0),
- (back_length*length_x, length_y),
- arrowstyle=arrowstyle,
- shrinkA=0.0,
- shrinkB=0.0,
- **arrow_props)
-
- self.box.add_artist(self.arrow_x)
- self.box.add_artist(self.arrow_y)
-
- text_path_x = TextPath((
- length_x+sep_x, back_length*length_y+sep_y), label_x,
- size=fontsize, prop=fontproperties)
- self.p_x = PathPatch(text_path_x, transform=t_start, **text_props)
- self.box.add_artist(self.p_x)
-
- text_path_y = TextPath((
- length_x*back_length+sep_x, length_y*(1-back_length)+sep_y),
- label_y, size=fontsize, prop=fontproperties)
- self.p_y = PathPatch(text_path_y, **text_props)
- self.box.add_artist(self.p_y)
-
- super().__init__(loc, pad=pad, borderpad=borderpad, child=self.box,
- frameon=frameon, **kwargs)
diff --git a/contrib/python/matplotlib/py3/mpl_toolkits/axes_grid1/axes_divider.py b/contrib/python/matplotlib/py3/mpl_toolkits/axes_grid1/axes_divider.py
deleted file mode 100644
index f6c38f35dbc..00000000000
--- a/contrib/python/matplotlib/py3/mpl_toolkits/axes_grid1/axes_divider.py
+++ /dev/null
@@ -1,694 +0,0 @@
-"""
-Helper classes to adjust the positions of multiple axes at drawing time.
-"""
-
-import functools
-
-import numpy as np
-
-import matplotlib as mpl
-from matplotlib import _api
-from matplotlib.gridspec import SubplotSpec
-import matplotlib.transforms as mtransforms
-from . import axes_size as Size
-
-
-class Divider:
- """
- An Axes positioning class.
-
- The divider is initialized with lists of horizontal and vertical sizes
- (:mod:`mpl_toolkits.axes_grid1.axes_size`) based on which a given
- rectangular area will be divided.
-
- The `new_locator` method then creates a callable object
- that can be used as the *axes_locator* of the axes.
- """
-
- def __init__(self, fig, pos, horizontal, vertical,
- aspect=None, anchor="C"):
- """
- Parameters
- ----------
- fig : Figure
- pos : tuple of 4 floats
- Position of the rectangle that will be divided.
- horizontal : list of :mod:`~mpl_toolkits.axes_grid1.axes_size`
- Sizes for horizontal division.
- vertical : list of :mod:`~mpl_toolkits.axes_grid1.axes_size`
- Sizes for vertical division.
- aspect : bool, optional
- Whether overall rectangular area is reduced so that the relative
- part of the horizontal and vertical scales have the same scale.
- anchor : (float, float) or {'C', 'SW', 'S', 'SE', 'E', 'NE', 'N', \
-'NW', 'W'}, default: 'C'
- Placement of the reduced rectangle, when *aspect* is True.
- """
-
- self._fig = fig
- self._pos = pos
- self._horizontal = horizontal
- self._vertical = vertical
- self._anchor = anchor
- self.set_anchor(anchor)
- self._aspect = aspect
- self._xrefindex = 0
- self._yrefindex = 0
- self._locator = None
-
- def get_horizontal_sizes(self, renderer):
- return np.array([s.get_size(renderer) for s in self.get_horizontal()])
-
- def get_vertical_sizes(self, renderer):
- return np.array([s.get_size(renderer) for s in self.get_vertical()])
-
- def set_position(self, pos):
- """
- Set the position of the rectangle.
-
- Parameters
- ----------
- pos : tuple of 4 floats
- position of the rectangle that will be divided
- """
- self._pos = pos
-
- def get_position(self):
- """Return the position of the rectangle."""
- return self._pos
-
- def set_anchor(self, anchor):
- """
- Parameters
- ----------
- anchor : (float, float) or {'C', 'SW', 'S', 'SE', 'E', 'NE', 'N', \
-'NW', 'W'}
- Either an (*x*, *y*) pair of relative coordinates (0 is left or
- bottom, 1 is right or top), 'C' (center), or a cardinal direction
- ('SW', southwest, is bottom left, etc.).
-
- See Also
- --------
- .Axes.set_anchor
- """
- if isinstance(anchor, str):
- _api.check_in_list(mtransforms.Bbox.coefs, anchor=anchor)
- elif not isinstance(anchor, (tuple, list)) or len(anchor) != 2:
- raise TypeError("anchor must be str or 2-tuple")
- self._anchor = anchor
-
- def get_anchor(self):
- """Return the anchor."""
- return self._anchor
-
- def get_subplotspec(self):
- return None
-
- def set_horizontal(self, h):
- """
- Parameters
- ----------
- h : list of :mod:`~mpl_toolkits.axes_grid1.axes_size`
- sizes for horizontal division
- """
- self._horizontal = h
-
- def get_horizontal(self):
- """Return horizontal sizes."""
- return self._horizontal
-
- def set_vertical(self, v):
- """
- Parameters
- ----------
- v : list of :mod:`~mpl_toolkits.axes_grid1.axes_size`
- sizes for vertical division
- """
- self._vertical = v
-
- def get_vertical(self):
- """Return vertical sizes."""
- return self._vertical
-
- def set_aspect(self, aspect=False):
- """
- Parameters
- ----------
- aspect : bool
- """
- self._aspect = aspect
-
- def get_aspect(self):
- """Return aspect."""
- return self._aspect
-
- def set_locator(self, _locator):
- self._locator = _locator
-
- def get_locator(self):
- return self._locator
-
- def get_position_runtime(self, ax, renderer):
- if self._locator is None:
- return self.get_position()
- else:
- return self._locator(ax, renderer).bounds
-
- @staticmethod
- def _calc_k(sizes, total):
- # sizes is a (n, 2) array of (rel_size, abs_size); this method finds
- # the k factor such that sum(rel_size * k + abs_size) == total.
- rel_sum, abs_sum = sizes.sum(0)
- return (total - abs_sum) / rel_sum if rel_sum else 0
-
- @staticmethod
- def _calc_offsets(sizes, k):
- # Apply k factors to (n, 2) sizes array of (rel_size, abs_size); return
- # the resulting cumulative offset positions.
- return np.cumsum([0, *(sizes @ [k, 1])])
-
- def new_locator(self, nx, ny, nx1=None, ny1=None):
- """
- Return an axes locator callable for the specified cell.
-
- Parameters
- ----------
- nx, nx1 : int
- Integers specifying the column-position of the
- cell. When *nx1* is None, a single *nx*-th column is
- specified. Otherwise, location of columns spanning between *nx*
- to *nx1* (but excluding *nx1*-th column) is specified.
- ny, ny1 : int
- Same as *nx* and *nx1*, but for row positions.
- """
- if nx1 is None:
- nx1 = nx + 1
- if ny1 is None:
- ny1 = ny + 1
- # append_size("left") adds a new size at the beginning of the
- # horizontal size lists; this shift transforms e.g.
- # new_locator(nx=2, ...) into effectively new_locator(nx=3, ...). To
- # take that into account, instead of recording nx, we record
- # nx-self._xrefindex, where _xrefindex is shifted by 1 by each
- # append_size("left"), and re-add self._xrefindex back to nx in
- # _locate, when the actual axes position is computed. Ditto for y.
- xref = self._xrefindex
- yref = self._yrefindex
- locator = functools.partial(
- self._locate, nx - xref, ny - yref, nx1 - xref, ny1 - yref)
- locator.get_subplotspec = self.get_subplotspec
- return locator
-
- @_api.deprecated(
- "3.8", alternative="divider.new_locator(...)(ax, renderer)")
- def locate(self, nx, ny, nx1=None, ny1=None, axes=None, renderer=None):
- """
- Implementation of ``divider.new_locator().__call__``.
-
- Parameters
- ----------
- nx, nx1 : int
- Integers specifying the column-position of the cell. When *nx1* is
- None, a single *nx*-th column is specified. Otherwise, the
- location of columns spanning between *nx* to *nx1* (but excluding
- *nx1*-th column) is specified.
- ny, ny1 : int
- Same as *nx* and *nx1*, but for row positions.
- axes
- renderer
- """
- xref = self._xrefindex
- yref = self._yrefindex
- return self._locate(
- nx - xref, (nx + 1 if nx1 is None else nx1) - xref,
- ny - yref, (ny + 1 if ny1 is None else ny1) - yref,
- axes, renderer)
-
- def _locate(self, nx, ny, nx1, ny1, axes, renderer):
- """
- Implementation of ``divider.new_locator().__call__``.
-
- The axes locator callable returned by ``new_locator()`` is created as
- a `functools.partial` of this method with *nx*, *ny*, *nx1*, and *ny1*
- specifying the requested cell.
- """
- nx += self._xrefindex
- nx1 += self._xrefindex
- ny += self._yrefindex
- ny1 += self._yrefindex
-
- fig_w, fig_h = self._fig.bbox.size / self._fig.dpi
- x, y, w, h = self.get_position_runtime(axes, renderer)
-
- hsizes = self.get_horizontal_sizes(renderer)
- vsizes = self.get_vertical_sizes(renderer)
- k_h = self._calc_k(hsizes, fig_w * w)
- k_v = self._calc_k(vsizes, fig_h * h)
-
- if self.get_aspect():
- k = min(k_h, k_v)
- ox = self._calc_offsets(hsizes, k)
- oy = self._calc_offsets(vsizes, k)
-
- ww = (ox[-1] - ox[0]) / fig_w
- hh = (oy[-1] - oy[0]) / fig_h
- pb = mtransforms.Bbox.from_bounds(x, y, w, h)
- pb1 = mtransforms.Bbox.from_bounds(x, y, ww, hh)
- x0, y0 = pb1.anchored(self.get_anchor(), pb).p0
-
- else:
- ox = self._calc_offsets(hsizes, k_h)
- oy = self._calc_offsets(vsizes, k_v)
- x0, y0 = x, y
-
- if nx1 is None:
- nx1 = -1
- if ny1 is None:
- ny1 = -1
-
- x1, w1 = x0 + ox[nx] / fig_w, (ox[nx1] - ox[nx]) / fig_w
- y1, h1 = y0 + oy[ny] / fig_h, (oy[ny1] - oy[ny]) / fig_h
-
- return mtransforms.Bbox.from_bounds(x1, y1, w1, h1)
-
- def append_size(self, position, size):
- _api.check_in_list(["left", "right", "bottom", "top"],
- position=position)
- if position == "left":
- self._horizontal.insert(0, size)
- self._xrefindex += 1
- elif position == "right":
- self._horizontal.append(size)
- elif position == "bottom":
- self._vertical.insert(0, size)
- self._yrefindex += 1
- else: # 'top'
- self._vertical.append(size)
-
- def add_auto_adjustable_area(self, use_axes, pad=0.1, adjust_dirs=None):
- """
- Add auto-adjustable padding around *use_axes* to take their decorations
- (title, labels, ticks, ticklabels) into account during layout.
-
- Parameters
- ----------
- use_axes : `~matplotlib.axes.Axes` or list of `~matplotlib.axes.Axes`
- The Axes whose decorations are taken into account.
- pad : float, default: 0.1
- Additional padding in inches.
- adjust_dirs : list of {"left", "right", "bottom", "top"}, optional
- The sides where padding is added; defaults to all four sides.
- """
- if adjust_dirs is None:
- adjust_dirs = ["left", "right", "bottom", "top"]
- for d in adjust_dirs:
- self.append_size(d, Size._AxesDecorationsSize(use_axes, d) + pad)
-
-
-@_api.deprecated("3.8")
-class AxesLocator:
- """
- A callable object which returns the position and size of a given
- `.AxesDivider` cell.
- """
-
- def __init__(self, axes_divider, nx, ny, nx1=None, ny1=None):
- """
- Parameters
- ----------
- axes_divider : `~mpl_toolkits.axes_grid1.axes_divider.AxesDivider`
- nx, nx1 : int
- Integers specifying the column-position of the
- cell. When *nx1* is None, a single *nx*-th column is
- specified. Otherwise, location of columns spanning between *nx*
- to *nx1* (but excluding *nx1*-th column) is specified.
- ny, ny1 : int
- Same as *nx* and *nx1*, but for row positions.
- """
- self._axes_divider = axes_divider
-
- _xrefindex = axes_divider._xrefindex
- _yrefindex = axes_divider._yrefindex
-
- self._nx, self._ny = nx - _xrefindex, ny - _yrefindex
-
- if nx1 is None:
- nx1 = len(self._axes_divider)
- if ny1 is None:
- ny1 = len(self._axes_divider[0])
-
- self._nx1 = nx1 - _xrefindex
- self._ny1 = ny1 - _yrefindex
-
- def __call__(self, axes, renderer):
-
- _xrefindex = self._axes_divider._xrefindex
- _yrefindex = self._axes_divider._yrefindex
-
- return self._axes_divider.locate(self._nx + _xrefindex,
- self._ny + _yrefindex,
- self._nx1 + _xrefindex,
- self._ny1 + _yrefindex,
- axes,
- renderer)
-
- def get_subplotspec(self):
- return self._axes_divider.get_subplotspec()
-
-
-class SubplotDivider(Divider):
- """
- The Divider class whose rectangle area is specified as a subplot geometry.
- """
-
- def __init__(self, fig, *args, horizontal=None, vertical=None,
- aspect=None, anchor='C'):
- """
- 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)).
- horizontal : list of :mod:`~mpl_toolkits.axes_grid1.axes_size`, optional
- Sizes for horizontal division.
- vertical : list of :mod:`~mpl_toolkits.axes_grid1.axes_size`, optional
- Sizes for vertical division.
- aspect : bool, optional
- Whether overall rectangular area is reduced so that the relative
- part of the horizontal and vertical scales have the same scale.
- anchor : (float, float) or {'C', 'SW', 'S', 'SE', 'E', 'NE', 'N', \
-'NW', 'W'}, default: 'C'
- Placement of the reduced rectangle, when *aspect* is True.
- """
- self.figure = fig
- super().__init__(fig, [0, 0, 1, 1],
- horizontal=horizontal or [], vertical=vertical or [],
- aspect=aspect, anchor=anchor)
- self.set_subplotspec(SubplotSpec._from_subplot_args(fig, args))
-
- def get_position(self):
- """Return the bounds of the subplot box."""
- return self.get_subplotspec().get_position(self.figure).bounds
-
- def get_subplotspec(self):
- """Get the SubplotSpec instance."""
- return self._subplotspec
-
- def set_subplotspec(self, subplotspec):
- """Set the SubplotSpec instance."""
- self._subplotspec = subplotspec
- self.set_position(subplotspec.get_position(self.figure))
-
-
-class AxesDivider(Divider):
- """
- Divider based on the preexisting axes.
- """
-
- def __init__(self, axes, xref=None, yref=None):
- """
- Parameters
- ----------
- axes : :class:`~matplotlib.axes.Axes`
- xref
- yref
- """
- self._axes = axes
- if xref is None:
- self._xref = Size.AxesX(axes)
- else:
- self._xref = xref
- if yref is None:
- self._yref = Size.AxesY(axes)
- else:
- self._yref = yref
-
- super().__init__(fig=axes.get_figure(), pos=None,
- horizontal=[self._xref], vertical=[self._yref],
- aspect=None, anchor="C")
-
- def _get_new_axes(self, *, axes_class=None, **kwargs):
- axes = self._axes
- if axes_class is None:
- axes_class = type(axes)
- return axes_class(axes.get_figure(), axes.get_position(original=True),
- **kwargs)
-
- def new_horizontal(self, size, pad=None, pack_start=False, **kwargs):
- """
- Helper method for ``append_axes("left")`` and ``append_axes("right")``.
-
- See the documentation of `append_axes` for more details.
-
- :meta private:
- """
- if pad is None:
- pad = mpl.rcParams["figure.subplot.wspace"] * self._xref
- pos = "left" if pack_start else "right"
- if pad:
- if not isinstance(pad, Size._Base):
- pad = Size.from_any(pad, fraction_ref=self._xref)
- self.append_size(pos, pad)
- if not isinstance(size, Size._Base):
- size = Size.from_any(size, fraction_ref=self._xref)
- self.append_size(pos, size)
- locator = self.new_locator(
- nx=0 if pack_start else len(self._horizontal) - 1,
- ny=self._yrefindex)
- ax = self._get_new_axes(**kwargs)
- ax.set_axes_locator(locator)
- return ax
-
- def new_vertical(self, size, pad=None, pack_start=False, **kwargs):
- """
- Helper method for ``append_axes("top")`` and ``append_axes("bottom")``.
-
- See the documentation of `append_axes` for more details.
-
- :meta private:
- """
- if pad is None:
- pad = mpl.rcParams["figure.subplot.hspace"] * self._yref
- pos = "bottom" if pack_start else "top"
- if pad:
- if not isinstance(pad, Size._Base):
- pad = Size.from_any(pad, fraction_ref=self._yref)
- self.append_size(pos, pad)
- if not isinstance(size, Size._Base):
- size = Size.from_any(size, fraction_ref=self._yref)
- self.append_size(pos, size)
- locator = self.new_locator(
- nx=self._xrefindex,
- ny=0 if pack_start else len(self._vertical) - 1)
- ax = self._get_new_axes(**kwargs)
- ax.set_axes_locator(locator)
- return ax
-
- def append_axes(self, position, size, pad=None, *, axes_class=None,
- **kwargs):
- """
- Add a new axes on a given side of the main axes.
-
- Parameters
- ----------
- position : {"left", "right", "bottom", "top"}
- Where the new axes is positioned relative to the main axes.
- size : :mod:`~mpl_toolkits.axes_grid1.axes_size` or float or str
- The axes width or height. float or str arguments are interpreted
- as ``axes_size.from_any(size, AxesX(<main_axes>))`` for left or
- right axes, and likewise with ``AxesY`` for bottom or top axes.
- pad : :mod:`~mpl_toolkits.axes_grid1.axes_size` or float or str
- Padding between the axes. float or str arguments are interpreted
- as for *size*. Defaults to :rc:`figure.subplot.wspace` times the
- main Axes width (left or right axes) or :rc:`figure.subplot.hspace`
- times the main Axes height (bottom or top axes).
- axes_class : subclass type of `~.axes.Axes`, optional
- The type of the new axes. Defaults to the type of the main axes.
- **kwargs
- All extra keywords arguments are passed to the created axes.
- """
- create_axes, pack_start = _api.check_getitem({
- "left": (self.new_horizontal, True),
- "right": (self.new_horizontal, False),
- "bottom": (self.new_vertical, True),
- "top": (self.new_vertical, False),
- }, position=position)
- ax = create_axes(
- size, pad, pack_start=pack_start, axes_class=axes_class, **kwargs)
- self._fig.add_axes(ax)
- return ax
-
- def get_aspect(self):
- if self._aspect is None:
- aspect = self._axes.get_aspect()
- if aspect == "auto":
- return False
- else:
- return True
- else:
- return self._aspect
-
- def get_position(self):
- if self._pos is None:
- bbox = self._axes.get_position(original=True)
- return bbox.bounds
- else:
- return self._pos
-
- def get_anchor(self):
- if self._anchor is None:
- return self._axes.get_anchor()
- else:
- return self._anchor
-
- def get_subplotspec(self):
- return self._axes.get_subplotspec()
-
-
-# Helper for HBoxDivider/VBoxDivider.
-# The variable names are written for a horizontal layout, but the calculations
-# work identically for vertical layouts.
-def _locate(x, y, w, h, summed_widths, equal_heights, fig_w, fig_h, anchor):
-
- total_width = fig_w * w
- max_height = fig_h * h
-
- # Determine the k factors.
- n = len(equal_heights)
- eq_rels, eq_abss = equal_heights.T
- sm_rels, sm_abss = summed_widths.T
- A = np.diag([*eq_rels, 0])
- A[:n, -1] = -1
- A[-1, :-1] = sm_rels
- B = [*(-eq_abss), total_width - sm_abss.sum()]
- # A @ K = B: This finds factors {k_0, ..., k_{N-1}, H} so that
- # eq_rel_i * k_i + eq_abs_i = H for all i: all axes have the same height
- # sum(sm_rel_i * k_i + sm_abs_i) = total_width: fixed total width
- # (foo_rel_i * k_i + foo_abs_i will end up being the size of foo.)
- *karray, height = np.linalg.solve(A, B)
- if height > max_height: # Additionally, upper-bound the height.
- karray = (max_height - eq_abss) / eq_rels
-
- # Compute the offsets corresponding to these factors.
- ox = np.cumsum([0, *(sm_rels * karray + sm_abss)])
- ww = (ox[-1] - ox[0]) / fig_w
- h0_rel, h0_abs = equal_heights[0]
- hh = (karray[0]*h0_rel + h0_abs) / fig_h
- pb = mtransforms.Bbox.from_bounds(x, y, w, h)
- pb1 = mtransforms.Bbox.from_bounds(x, y, ww, hh)
- x0, y0 = pb1.anchored(anchor, pb).p0
-
- return x0, y0, ox, hh
-
-
-class HBoxDivider(SubplotDivider):
- """
- A `.SubplotDivider` for laying out axes horizontally, while ensuring that
- they have equal heights.
-
- Examples
- --------
- .. plot:: gallery/axes_grid1/demo_axes_hbox_divider.py
- """
-
- def new_locator(self, nx, nx1=None):
- """
- Create an axes locator callable for the specified cell.
-
- Parameters
- ----------
- nx, nx1 : int
- Integers specifying the column-position of the
- cell. When *nx1* is None, a single *nx*-th column is
- specified. Otherwise, location of columns spanning between *nx*
- to *nx1* (but excluding *nx1*-th column) is specified.
- """
- return super().new_locator(nx, 0, nx1, 0)
-
- def _locate(self, nx, ny, nx1, ny1, axes, renderer):
- # docstring inherited
- nx += self._xrefindex
- nx1 += self._xrefindex
- fig_w, fig_h = self._fig.bbox.size / self._fig.dpi
- x, y, w, h = self.get_position_runtime(axes, renderer)
- summed_ws = self.get_horizontal_sizes(renderer)
- equal_hs = self.get_vertical_sizes(renderer)
- x0, y0, ox, hh = _locate(
- x, y, w, h, summed_ws, equal_hs, fig_w, fig_h, self.get_anchor())
- if nx1 is None:
- nx1 = -1
- x1, w1 = x0 + ox[nx] / fig_w, (ox[nx1] - ox[nx]) / fig_w
- y1, h1 = y0, hh
- return mtransforms.Bbox.from_bounds(x1, y1, w1, h1)
-
-
-class VBoxDivider(SubplotDivider):
- """
- A `.SubplotDivider` for laying out axes vertically, while ensuring that
- they have equal widths.
- """
-
- def new_locator(self, ny, ny1=None):
- """
- Create an axes locator callable for the specified cell.
-
- Parameters
- ----------
- ny, ny1 : int
- Integers specifying the row-position of the
- cell. When *ny1* is None, a single *ny*-th row is
- specified. Otherwise, location of rows spanning between *ny*
- to *ny1* (but excluding *ny1*-th row) is specified.
- """
- return super().new_locator(0, ny, 0, ny1)
-
- def _locate(self, nx, ny, nx1, ny1, axes, renderer):
- # docstring inherited
- ny += self._yrefindex
- ny1 += self._yrefindex
- fig_w, fig_h = self._fig.bbox.size / self._fig.dpi
- x, y, w, h = self.get_position_runtime(axes, renderer)
- summed_hs = self.get_vertical_sizes(renderer)
- equal_ws = self.get_horizontal_sizes(renderer)
- y0, x0, oy, ww = _locate(
- y, x, h, w, summed_hs, equal_ws, fig_h, fig_w, self.get_anchor())
- if ny1 is None:
- ny1 = -1
- x1, w1 = x0, ww
- y1, h1 = y0 + oy[ny] / fig_h, (oy[ny1] - oy[ny]) / fig_h
- return mtransforms.Bbox.from_bounds(x1, y1, w1, h1)
-
-
-def make_axes_locatable(axes):
- divider = AxesDivider(axes)
- locator = divider.new_locator(nx=0, ny=0)
- axes.set_axes_locator(locator)
-
- return divider
-
-
-def make_axes_area_auto_adjustable(
- ax, use_axes=None, pad=0.1, adjust_dirs=None):
- """
- Add auto-adjustable padding around *ax* to take its decorations (title,
- labels, ticks, ticklabels) into account during layout, using
- `.Divider.add_auto_adjustable_area`.
-
- By default, padding is determined from the decorations of *ax*.
- Pass *use_axes* to consider the decorations of other Axes instead.
- """
- if adjust_dirs is None:
- adjust_dirs = ["left", "right", "bottom", "top"]
- divider = make_axes_locatable(ax)
- if use_axes is None:
- use_axes = ax
- divider.add_auto_adjustable_area(use_axes=use_axes, pad=pad,
- adjust_dirs=adjust_dirs)
diff --git a/contrib/python/matplotlib/py3/mpl_toolkits/axes_grid1/axes_grid.py b/contrib/python/matplotlib/py3/mpl_toolkits/axes_grid1/axes_grid.py
deleted file mode 100644
index 720d985414f..00000000000
--- a/contrib/python/matplotlib/py3/mpl_toolkits/axes_grid1/axes_grid.py
+++ /dev/null
@@ -1,550 +0,0 @@
-from numbers import Number
-import functools
-from types import MethodType
-
-import numpy as np
-
-from matplotlib import _api, cbook
-from matplotlib.gridspec import SubplotSpec
-
-from .axes_divider import Size, SubplotDivider, Divider
-from .mpl_axes import Axes, SimpleAxisArtist
-
-
-class CbarAxesBase:
- def __init__(self, *args, orientation, **kwargs):
- self.orientation = orientation
- super().__init__(*args, **kwargs)
-
- def colorbar(self, mappable, **kwargs):
- return self.figure.colorbar(
- mappable, cax=self, location=self.orientation, **kwargs)
-
- @_api.deprecated("3.8", alternative="ax.tick_params and colorbar.set_label")
- def toggle_label(self, b):
- axis = self.axis[self.orientation]
- axis.toggle(ticklabels=b, label=b)
-
-
-_cbaraxes_class_factory = cbook._make_class_factory(CbarAxesBase, "Cbar{}")
-
-
-class Grid:
- """
- A grid of Axes.
-
- In Matplotlib, the Axes location (and size) is specified in normalized
- figure coordinates. This may not be ideal for images that needs to be
- displayed with a given aspect ratio; for example, it is difficult to
- display multiple images of a same size with some fixed padding between
- them. AxesGrid can be used in such case.
- """
-
- _defaultAxesClass = Axes
-
- def __init__(self, fig,
- rect,
- nrows_ncols,
- ngrids=None,
- direction="row",
- axes_pad=0.02,
- *,
- share_all=False,
- share_x=True,
- share_y=True,
- label_mode="L",
- axes_class=None,
- aspect=False,
- ):
- """
- Parameters
- ----------
- fig : `.Figure`
- The parent figure.
- rect : (float, float, float, float), (int, int, int), int, or \
- `~.SubplotSpec`
- The axes position, as a ``(left, bottom, width, height)`` tuple,
- as a three-digit subplot position code (e.g., ``(1, 2, 1)`` or
- ``121``), or as a `~.SubplotSpec`.
- nrows_ncols : (int, int)
- Number of rows and columns in the grid.
- ngrids : int or None, default: None
- If not None, only the first *ngrids* axes in the grid are created.
- direction : {"row", "column"}, default: "row"
- Whether axes are created in row-major ("row by row") or
- column-major order ("column by column"). This also affects the
- order in which axes are accessed using indexing (``grid[index]``).
- axes_pad : float or (float, float), default: 0.02
- Padding or (horizontal padding, vertical padding) between axes, in
- inches.
- share_all : bool, default: False
- Whether all axes share their x- and y-axis. Overrides *share_x*
- and *share_y*.
- share_x : bool, default: True
- Whether all axes of a column share their x-axis.
- share_y : bool, default: True
- Whether all axes of a row share their y-axis.
- label_mode : {"L", "1", "all", "keep"}, default: "L"
- Determines which axes will get tick labels:
-
- - "L": All axes on the left column get vertical tick labels;
- all axes on the bottom row get horizontal tick labels.
- - "1": Only the bottom left axes is labelled.
- - "all": All axes are labelled.
- - "keep": Do not do anything.
-
- axes_class : subclass of `matplotlib.axes.Axes`, default: None
- aspect : bool, default: False
- Whether the axes aspect ratio follows the aspect ratio of the data
- limits.
- """
- self._nrows, self._ncols = nrows_ncols
-
- if ngrids is None:
- ngrids = self._nrows * self._ncols
- else:
- if not 0 < ngrids <= self._nrows * self._ncols:
- raise ValueError(
- "ngrids must be positive and not larger than nrows*ncols")
-
- self.ngrids = ngrids
-
- self._horiz_pad_size, self._vert_pad_size = map(
- Size.Fixed, np.broadcast_to(axes_pad, 2))
-
- _api.check_in_list(["column", "row"], direction=direction)
- self._direction = direction
-
- if axes_class is None:
- axes_class = self._defaultAxesClass
- elif isinstance(axes_class, (list, tuple)):
- cls, kwargs = axes_class
- axes_class = functools.partial(cls, **kwargs)
-
- kw = dict(horizontal=[], vertical=[], aspect=aspect)
- if isinstance(rect, (Number, SubplotSpec)):
- self._divider = SubplotDivider(fig, rect, **kw)
- elif len(rect) == 3:
- self._divider = SubplotDivider(fig, *rect, **kw)
- elif len(rect) == 4:
- self._divider = Divider(fig, rect, **kw)
- else:
- raise TypeError("Incorrect rect format")
-
- rect = self._divider.get_position()
-
- axes_array = np.full((self._nrows, self._ncols), None, dtype=object)
- for i in range(self.ngrids):
- col, row = self._get_col_row(i)
- if share_all:
- sharex = sharey = axes_array[0, 0]
- else:
- sharex = axes_array[0, col] if share_x else None
- sharey = axes_array[row, 0] if share_y else None
- axes_array[row, col] = axes_class(
- fig, rect, sharex=sharex, sharey=sharey)
- self.axes_all = axes_array.ravel(
- order="C" if self._direction == "row" else "F").tolist()
- self.axes_column = axes_array.T.tolist()
- self.axes_row = axes_array.tolist()
- self.axes_llc = self.axes_column[0][-1]
-
- self._init_locators()
-
- for ax in self.axes_all:
- fig.add_axes(ax)
-
- self.set_label_mode(label_mode)
-
- def _init_locators(self):
- self._divider.set_horizontal(
- [Size.Scaled(1), self._horiz_pad_size] * (self._ncols-1) + [Size.Scaled(1)])
- self._divider.set_vertical(
- [Size.Scaled(1), self._vert_pad_size] * (self._nrows-1) + [Size.Scaled(1)])
- for i in range(self.ngrids):
- col, row = self._get_col_row(i)
- self.axes_all[i].set_axes_locator(
- self._divider.new_locator(nx=2 * col, ny=2 * (self._nrows - 1 - row)))
-
- def _get_col_row(self, n):
- if self._direction == "column":
- col, row = divmod(n, self._nrows)
- else:
- row, col = divmod(n, self._ncols)
-
- return col, row
-
- # Good to propagate __len__ if we have __getitem__
- def __len__(self):
- return len(self.axes_all)
-
- def __getitem__(self, i):
- return self.axes_all[i]
-
- def get_geometry(self):
- """
- Return the number of rows and columns of the grid as (nrows, ncols).
- """
- return self._nrows, self._ncols
-
- def set_axes_pad(self, axes_pad):
- """
- Set the padding between the axes.
-
- Parameters
- ----------
- axes_pad : (float, float)
- The padding (horizontal pad, vertical pad) in inches.
- """
- self._horiz_pad_size.fixed_size = axes_pad[0]
- self._vert_pad_size.fixed_size = axes_pad[1]
-
- def get_axes_pad(self):
- """
- Return the axes padding.
-
- Returns
- -------
- hpad, vpad
- Padding (horizontal pad, vertical pad) in inches.
- """
- return (self._horiz_pad_size.fixed_size,
- self._vert_pad_size.fixed_size)
-
- def set_aspect(self, aspect):
- """Set the aspect of the SubplotDivider."""
- self._divider.set_aspect(aspect)
-
- def get_aspect(self):
- """Return the aspect of the SubplotDivider."""
- return self._divider.get_aspect()
-
- def set_label_mode(self, mode):
- """
- Define which axes have tick labels.
-
- Parameters
- ----------
- mode : {"L", "1", "all", "keep"}
- The label mode:
-
- - "L": All axes on the left column get vertical tick labels;
- all axes on the bottom row get horizontal tick labels.
- - "1": Only the bottom left axes is labelled.
- - "all": All axes are labelled.
- - "keep": Do not do anything.
- """
- is_last_row, is_first_col = (
- np.mgrid[:self._nrows, :self._ncols] == [[[self._nrows - 1]], [[0]]])
- if mode == "all":
- bottom = left = np.full((self._nrows, self._ncols), True)
- elif mode == "L":
- bottom = is_last_row
- left = is_first_col
- elif mode == "1":
- bottom = left = is_last_row & is_first_col
- else:
- # Use _api.check_in_list at the top of the method when deprecation
- # period expires
- if mode != 'keep':
- _api.warn_deprecated(
- '3.7', name="Grid label_mode",
- message='Passing an undefined label_mode is deprecated '
- 'since %(since)s and will become an error '
- '%(removal)s. To silence this warning, pass '
- '"keep", which gives the same behaviour.')
- return
- for i in range(self._nrows):
- for j in range(self._ncols):
- ax = self.axes_row[i][j]
- if isinstance(ax.axis, MethodType):
- bottom_axis = SimpleAxisArtist(ax.xaxis, 1, ax.spines["bottom"])
- left_axis = SimpleAxisArtist(ax.yaxis, 1, ax.spines["left"])
- else:
- bottom_axis = ax.axis["bottom"]
- left_axis = ax.axis["left"]
- bottom_axis.toggle(ticklabels=bottom[i, j], label=bottom[i, j])
- left_axis.toggle(ticklabels=left[i, j], label=left[i, j])
-
- def get_divider(self):
- return self._divider
-
- def set_axes_locator(self, locator):
- self._divider.set_locator(locator)
-
- def get_axes_locator(self):
- return self._divider.get_locator()
-
-
-class ImageGrid(Grid):
- """
- A grid of Axes for Image display.
-
- This class is a specialization of `~.axes_grid1.axes_grid.Grid` for displaying a
- grid of images. In particular, it forces all axes in a column to share their x-axis
- and all axes in a row to share their y-axis. It further provides helpers to add
- colorbars to some or all axes.
- """
-
- def __init__(self, fig,
- rect,
- nrows_ncols,
- ngrids=None,
- direction="row",
- axes_pad=0.02,
- *,
- share_all=False,
- aspect=True,
- label_mode="L",
- cbar_mode=None,
- cbar_location="right",
- cbar_pad=None,
- cbar_size="5%",
- cbar_set_cax=True,
- axes_class=None,
- ):
- """
- Parameters
- ----------
- fig : `.Figure`
- The parent figure.
- rect : (float, float, float, float) or int
- The axes position, as a ``(left, bottom, width, height)`` tuple or
- as a three-digit subplot position code (e.g., "121").
- nrows_ncols : (int, int)
- Number of rows and columns in the grid.
- ngrids : int or None, default: None
- If not None, only the first *ngrids* axes in the grid are created.
- direction : {"row", "column"}, default: "row"
- Whether axes are created in row-major ("row by row") or
- column-major order ("column by column"). This also affects the
- order in which axes are accessed using indexing (``grid[index]``).
- axes_pad : float or (float, float), default: 0.02in
- Padding or (horizontal padding, vertical padding) between axes, in
- inches.
- share_all : bool, default: False
- Whether all axes share their x- and y-axis. Note that in any case,
- all axes in a column share their x-axis and all axes in a row share
- their y-axis.
- aspect : bool, default: True
- Whether the axes aspect ratio follows the aspect ratio of the data
- limits.
- label_mode : {"L", "1", "all"}, default: "L"
- Determines which axes will get tick labels:
-
- - "L": All axes on the left column get vertical tick labels;
- all axes on the bottom row get horizontal tick labels.
- - "1": Only the bottom left axes is labelled.
- - "all": all axes are labelled.
-
- cbar_mode : {"each", "single", "edge", None}, default: None
- Whether to create a colorbar for "each" axes, a "single" colorbar
- for the entire grid, colorbars only for axes on the "edge"
- determined by *cbar_location*, or no colorbars. The colorbars are
- stored in the :attr:`cbar_axes` attribute.
- cbar_location : {"left", "right", "bottom", "top"}, default: "right"
- cbar_pad : float, default: None
- Padding between the image axes and the colorbar axes.
- cbar_size : size specification (see `.Size.from_any`), default: "5%"
- Colorbar size.
- cbar_set_cax : bool, default: True
- If True, each axes in the grid has a *cax* attribute that is bound
- to associated *cbar_axes*.
- axes_class : subclass of `matplotlib.axes.Axes`, default: None
- """
- _api.check_in_list(["each", "single", "edge", None],
- cbar_mode=cbar_mode)
- _api.check_in_list(["left", "right", "bottom", "top"],
- cbar_location=cbar_location)
- self._colorbar_mode = cbar_mode
- self._colorbar_location = cbar_location
- self._colorbar_pad = cbar_pad
- self._colorbar_size = cbar_size
- # The colorbar axes are created in _init_locators().
-
- super().__init__(
- fig, rect, nrows_ncols, ngrids,
- direction=direction, axes_pad=axes_pad,
- share_all=share_all, share_x=True, share_y=True, aspect=aspect,
- label_mode=label_mode, axes_class=axes_class)
-
- for ax in self.cbar_axes:
- fig.add_axes(ax)
-
- if cbar_set_cax:
- if self._colorbar_mode == "single":
- for ax in self.axes_all:
- ax.cax = self.cbar_axes[0]
- elif self._colorbar_mode == "edge":
- for index, ax in enumerate(self.axes_all):
- col, row = self._get_col_row(index)
- if self._colorbar_location in ("left", "right"):
- ax.cax = self.cbar_axes[row]
- else:
- ax.cax = self.cbar_axes[col]
- else:
- for ax, cax in zip(self.axes_all, self.cbar_axes):
- ax.cax = cax
-
- def _init_locators(self):
- # Slightly abusing this method to inject colorbar creation into init.
-
- if self._colorbar_pad is None:
- # horizontal or vertical arrangement?
- if self._colorbar_location in ("left", "right"):
- self._colorbar_pad = self._horiz_pad_size.fixed_size
- else:
- self._colorbar_pad = self._vert_pad_size.fixed_size
- self.cbar_axes = [
- _cbaraxes_class_factory(self._defaultAxesClass)(
- self.axes_all[0].figure, self._divider.get_position(),
- orientation=self._colorbar_location)
- for _ in range(self.ngrids)]
-
- cb_mode = self._colorbar_mode
- cb_location = self._colorbar_location
-
- h = []
- v = []
-
- h_ax_pos = []
- h_cb_pos = []
- if cb_mode == "single" and cb_location in ("left", "bottom"):
- if cb_location == "left":
- sz = self._nrows * Size.AxesX(self.axes_llc)
- h.append(Size.from_any(self._colorbar_size, sz))
- h.append(Size.from_any(self._colorbar_pad, sz))
- locator = self._divider.new_locator(nx=0, ny=0, ny1=-1)
- elif cb_location == "bottom":
- sz = self._ncols * Size.AxesY(self.axes_llc)
- v.append(Size.from_any(self._colorbar_size, sz))
- v.append(Size.from_any(self._colorbar_pad, sz))
- locator = self._divider.new_locator(nx=0, nx1=-1, ny=0)
- for i in range(self.ngrids):
- self.cbar_axes[i].set_visible(False)
- self.cbar_axes[0].set_axes_locator(locator)
- self.cbar_axes[0].set_visible(True)
-
- for col, ax in enumerate(self.axes_row[0]):
- if h:
- h.append(self._horiz_pad_size)
-
- if ax:
- sz = Size.AxesX(ax, aspect="axes", ref_ax=self.axes_all[0])
- else:
- sz = Size.AxesX(self.axes_all[0],
- aspect="axes", ref_ax=self.axes_all[0])
-
- if (cb_location == "left"
- and (cb_mode == "each"
- or (cb_mode == "edge" and col == 0))):
- h_cb_pos.append(len(h))
- h.append(Size.from_any(self._colorbar_size, sz))
- h.append(Size.from_any(self._colorbar_pad, sz))
-
- h_ax_pos.append(len(h))
- h.append(sz)
-
- if (cb_location == "right"
- and (cb_mode == "each"
- or (cb_mode == "edge" and col == self._ncols - 1))):
- h.append(Size.from_any(self._colorbar_pad, sz))
- h_cb_pos.append(len(h))
- h.append(Size.from_any(self._colorbar_size, sz))
-
- v_ax_pos = []
- v_cb_pos = []
- for row, ax in enumerate(self.axes_column[0][::-1]):
- if v:
- v.append(self._vert_pad_size)
-
- if ax:
- sz = Size.AxesY(ax, aspect="axes", ref_ax=self.axes_all[0])
- else:
- sz = Size.AxesY(self.axes_all[0],
- aspect="axes", ref_ax=self.axes_all[0])
-
- if (cb_location == "bottom"
- and (cb_mode == "each"
- or (cb_mode == "edge" and row == 0))):
- v_cb_pos.append(len(v))
- v.append(Size.from_any(self._colorbar_size, sz))
- v.append(Size.from_any(self._colorbar_pad, sz))
-
- v_ax_pos.append(len(v))
- v.append(sz)
-
- if (cb_location == "top"
- and (cb_mode == "each"
- or (cb_mode == "edge" and row == self._nrows - 1))):
- v.append(Size.from_any(self._colorbar_pad, sz))
- v_cb_pos.append(len(v))
- v.append(Size.from_any(self._colorbar_size, sz))
-
- for i in range(self.ngrids):
- col, row = self._get_col_row(i)
- locator = self._divider.new_locator(nx=h_ax_pos[col],
- ny=v_ax_pos[self._nrows-1-row])
- self.axes_all[i].set_axes_locator(locator)
-
- if cb_mode == "each":
- if cb_location in ("right", "left"):
- locator = self._divider.new_locator(
- nx=h_cb_pos[col], ny=v_ax_pos[self._nrows - 1 - row])
-
- elif cb_location in ("top", "bottom"):
- locator = self._divider.new_locator(
- nx=h_ax_pos[col], ny=v_cb_pos[self._nrows - 1 - row])
-
- self.cbar_axes[i].set_axes_locator(locator)
- elif cb_mode == "edge":
- if (cb_location == "left" and col == 0
- or cb_location == "right" and col == self._ncols - 1):
- locator = self._divider.new_locator(
- nx=h_cb_pos[0], ny=v_ax_pos[self._nrows - 1 - row])
- self.cbar_axes[row].set_axes_locator(locator)
- elif (cb_location == "bottom" and row == self._nrows - 1
- or cb_location == "top" and row == 0):
- locator = self._divider.new_locator(nx=h_ax_pos[col],
- ny=v_cb_pos[0])
- self.cbar_axes[col].set_axes_locator(locator)
-
- if cb_mode == "single":
- if cb_location == "right":
- sz = self._nrows * Size.AxesX(self.axes_llc)
- h.append(Size.from_any(self._colorbar_pad, sz))
- h.append(Size.from_any(self._colorbar_size, sz))
- locator = self._divider.new_locator(nx=-2, ny=0, ny1=-1)
- elif cb_location == "top":
- sz = self._ncols * Size.AxesY(self.axes_llc)
- v.append(Size.from_any(self._colorbar_pad, sz))
- v.append(Size.from_any(self._colorbar_size, sz))
- locator = self._divider.new_locator(nx=0, nx1=-1, ny=-2)
- if cb_location in ("right", "top"):
- for i in range(self.ngrids):
- self.cbar_axes[i].set_visible(False)
- self.cbar_axes[0].set_axes_locator(locator)
- self.cbar_axes[0].set_visible(True)
- elif cb_mode == "each":
- for i in range(self.ngrids):
- self.cbar_axes[i].set_visible(True)
- elif cb_mode == "edge":
- if cb_location in ("right", "left"):
- count = self._nrows
- else:
- count = self._ncols
- for i in range(count):
- self.cbar_axes[i].set_visible(True)
- for j in range(i + 1, self.ngrids):
- self.cbar_axes[j].set_visible(False)
- else:
- for i in range(self.ngrids):
- self.cbar_axes[i].set_visible(False)
- self.cbar_axes[i].set_position([1., 1., 0.001, 0.001],
- which="active")
-
- self._divider.set_horizontal(h)
- self._divider.set_vertical(v)
-
-
-AxesGrid = ImageGrid
diff --git a/contrib/python/matplotlib/py3/mpl_toolkits/axes_grid1/axes_rgb.py b/contrib/python/matplotlib/py3/mpl_toolkits/axes_grid1/axes_rgb.py
deleted file mode 100644
index 52fd707e870..00000000000
--- a/contrib/python/matplotlib/py3/mpl_toolkits/axes_grid1/axes_rgb.py
+++ /dev/null
@@ -1,157 +0,0 @@
-from types import MethodType
-
-import numpy as np
-
-from .axes_divider import make_axes_locatable, Size
-from .mpl_axes import Axes, SimpleAxisArtist
-
-
-def make_rgb_axes(ax, pad=0.01, axes_class=None, **kwargs):
- """
- Parameters
- ----------
- ax : `~matplotlib.axes.Axes`
- Axes instance to create the RGB Axes in.
- pad : float, optional
- Fraction of the Axes height to pad.
- axes_class : `matplotlib.axes.Axes` or None, optional
- Axes class to use for the R, G, and B Axes. If None, use
- the same class as *ax*.
- **kwargs
- Forwarded to *axes_class* init for the R, G, and B Axes.
- """
-
- divider = make_axes_locatable(ax)
-
- pad_size = pad * Size.AxesY(ax)
-
- xsize = ((1-2*pad)/3) * Size.AxesX(ax)
- ysize = ((1-2*pad)/3) * Size.AxesY(ax)
-
- divider.set_horizontal([Size.AxesX(ax), pad_size, xsize])
- divider.set_vertical([ysize, pad_size, ysize, pad_size, ysize])
-
- ax.set_axes_locator(divider.new_locator(0, 0, ny1=-1))
-
- ax_rgb = []
- if axes_class is None:
- axes_class = type(ax)
-
- for ny in [4, 2, 0]:
- ax1 = axes_class(ax.get_figure(), ax.get_position(original=True),
- sharex=ax, sharey=ax, **kwargs)
- locator = divider.new_locator(nx=2, ny=ny)
- ax1.set_axes_locator(locator)
- for t in ax1.yaxis.get_ticklabels() + ax1.xaxis.get_ticklabels():
- t.set_visible(False)
- try:
- for axis in ax1.axis.values():
- axis.major_ticklabels.set_visible(False)
- except AttributeError:
- pass
-
- ax_rgb.append(ax1)
-
- fig = ax.get_figure()
- for ax1 in ax_rgb:
- fig.add_axes(ax1)
-
- return ax_rgb
-
-
-class RGBAxes:
- """
- 4-panel `~.Axes.imshow` (RGB, R, G, B).
-
- Layout::
-
- ┌───────────────┬─────┐
- │ │ R │
- │ ├─────┤
- │ RGB │ G │
- │ ├─────┤
- │ │ B │
- └───────────────┴─────┘
-
- Subclasses can override the ``_defaultAxesClass`` attribute.
- By default RGBAxes uses `.mpl_axes.Axes`.
-
- Attributes
- ----------
- RGB : ``_defaultAxesClass``
- The Axes object for the three-channel `~.Axes.imshow`.
- R : ``_defaultAxesClass``
- The Axes object for the red channel `~.Axes.imshow`.
- G : ``_defaultAxesClass``
- The Axes object for the green channel `~.Axes.imshow`.
- B : ``_defaultAxesClass``
- The Axes object for the blue channel `~.Axes.imshow`.
- """
-
- _defaultAxesClass = Axes
-
- def __init__(self, *args, pad=0, **kwargs):
- """
- Parameters
- ----------
- pad : float, default: 0
- Fraction of the Axes height to put as padding.
- axes_class : `~matplotlib.axes.Axes`
- Axes class to use. If not provided, ``_defaultAxesClass`` is used.
- *args
- Forwarded to *axes_class* init for the RGB Axes
- **kwargs
- Forwarded to *axes_class* init for the RGB, R, G, and B Axes
- """
- axes_class = kwargs.pop("axes_class", self._defaultAxesClass)
- self.RGB = ax = axes_class(*args, **kwargs)
- ax.get_figure().add_axes(ax)
- self.R, self.G, self.B = make_rgb_axes(
- ax, pad=pad, axes_class=axes_class, **kwargs)
- # Set the line color and ticks for the axes.
- for ax1 in [self.RGB, self.R, self.G, self.B]:
- if isinstance(ax1.axis, MethodType):
- ad = Axes.AxisDict(self)
- ad.update(
- bottom=SimpleAxisArtist(ax1.xaxis, 1, ax1.spines["bottom"]),
- top=SimpleAxisArtist(ax1.xaxis, 2, ax1.spines["top"]),
- left=SimpleAxisArtist(ax1.yaxis, 1, ax1.spines["left"]),
- right=SimpleAxisArtist(ax1.yaxis, 2, ax1.spines["right"]))
- else:
- ad = ax1.axis
- ad[:].line.set_color("w")
- ad[:].major_ticks.set_markeredgecolor("w")
-
- def imshow_rgb(self, r, g, b, **kwargs):
- """
- Create the four images {rgb, r, g, b}.
-
- Parameters
- ----------
- r, g, b : array-like
- The red, green, and blue arrays.
- **kwargs
- Forwarded to `~.Axes.imshow` calls for the four images.
-
- Returns
- -------
- rgb : `~matplotlib.image.AxesImage`
- r : `~matplotlib.image.AxesImage`
- g : `~matplotlib.image.AxesImage`
- b : `~matplotlib.image.AxesImage`
- """
- if not (r.shape == g.shape == b.shape):
- raise ValueError(
- f'Input shapes ({r.shape}, {g.shape}, {b.shape}) do not match')
- RGB = np.dstack([r, g, b])
- R = np.zeros_like(RGB)
- R[:, :, 0] = r
- G = np.zeros_like(RGB)
- G[:, :, 1] = g
- B = np.zeros_like(RGB)
- B[:, :, 2] = b
- im_rgb = self.RGB.imshow(RGB, **kwargs)
- im_r = self.R.imshow(R, **kwargs)
- im_g = self.G.imshow(G, **kwargs)
- im_b = self.B.imshow(B, **kwargs)
- return im_rgb, im_r, im_g, im_b
diff --git a/contrib/python/matplotlib/py3/mpl_toolkits/axes_grid1/axes_size.py b/contrib/python/matplotlib/py3/mpl_toolkits/axes_grid1/axes_size.py
deleted file mode 100644
index d2514720772..00000000000
--- a/contrib/python/matplotlib/py3/mpl_toolkits/axes_grid1/axes_size.py
+++ /dev/null
@@ -1,248 +0,0 @@
-"""
-Provides classes of simple units that will be used with `.AxesDivider`
-class (or others) to determine the size of each Axes. The unit
-classes define `get_size` method that returns a tuple of two floats,
-meaning relative and absolute sizes, respectively.
-
-Note that this class is nothing more than a simple tuple of two
-floats. Take a look at the Divider class to see how these two
-values are used.
-"""
-
-from numbers import Real
-
-from matplotlib import _api
-from matplotlib.axes import Axes
-
-
-class _Base:
- def __rmul__(self, other):
- return Fraction(other, self)
-
- def __add__(self, other):
- if isinstance(other, _Base):
- return Add(self, other)
- else:
- return Add(self, Fixed(other))
-
- def get_size(self, renderer):
- """
- Return two-float tuple with relative and absolute sizes.
- """
- raise NotImplementedError("Subclasses must implement")
-
-
-class Add(_Base):
- """
- Sum of two sizes.
- """
-
- def __init__(self, a, b):
- self._a = a
- self._b = b
-
- def get_size(self, renderer):
- a_rel_size, a_abs_size = self._a.get_size(renderer)
- b_rel_size, b_abs_size = self._b.get_size(renderer)
- return a_rel_size + b_rel_size, a_abs_size + b_abs_size
-
-
-class Fixed(_Base):
- """
- Simple fixed size with absolute part = *fixed_size* and relative part = 0.
- """
-
- def __init__(self, fixed_size):
- _api.check_isinstance(Real, fixed_size=fixed_size)
- self.fixed_size = fixed_size
-
- def get_size(self, renderer):
- rel_size = 0.
- abs_size = self.fixed_size
- return rel_size, abs_size
-
-
-class Scaled(_Base):
- """
- Simple scaled(?) size with absolute part = 0 and
- relative part = *scalable_size*.
- """
-
- def __init__(self, scalable_size):
- self._scalable_size = scalable_size
-
- def get_size(self, renderer):
- rel_size = self._scalable_size
- abs_size = 0.
- return rel_size, abs_size
-
-Scalable = Scaled
-
-
-def _get_axes_aspect(ax):
- aspect = ax.get_aspect()
- if aspect == "auto":
- aspect = 1.
- return aspect
-
-
-class AxesX(_Base):
- """
- Scaled size whose relative part corresponds to the data width
- of the *axes* multiplied by the *aspect*.
- """
-
- def __init__(self, axes, aspect=1., ref_ax=None):
- self._axes = axes
- self._aspect = aspect
- if aspect == "axes" and ref_ax is None:
- raise ValueError("ref_ax must be set when aspect='axes'")
- self._ref_ax = ref_ax
-
- def get_size(self, renderer):
- l1, l2 = self._axes.get_xlim()
- if self._aspect == "axes":
- ref_aspect = _get_axes_aspect(self._ref_ax)
- aspect = ref_aspect / _get_axes_aspect(self._axes)
- else:
- aspect = self._aspect
-
- rel_size = abs(l2-l1)*aspect
- abs_size = 0.
- return rel_size, abs_size
-
-
-class AxesY(_Base):
- """
- Scaled size whose relative part corresponds to the data height
- of the *axes* multiplied by the *aspect*.
- """
-
- def __init__(self, axes, aspect=1., ref_ax=None):
- self._axes = axes
- self._aspect = aspect
- if aspect == "axes" and ref_ax is None:
- raise ValueError("ref_ax must be set when aspect='axes'")
- self._ref_ax = ref_ax
-
- def get_size(self, renderer):
- l1, l2 = self._axes.get_ylim()
-
- if self._aspect == "axes":
- ref_aspect = _get_axes_aspect(self._ref_ax)
- aspect = _get_axes_aspect(self._axes)
- else:
- aspect = self._aspect
-
- rel_size = abs(l2-l1)*aspect
- abs_size = 0.
- return rel_size, abs_size
-
-
-class MaxExtent(_Base):
- """
- Size whose absolute part is either the largest width or the largest height
- of the given *artist_list*.
- """
-
- def __init__(self, artist_list, w_or_h):
- self._artist_list = artist_list
- _api.check_in_list(["width", "height"], w_or_h=w_or_h)
- self._w_or_h = w_or_h
-
- def add_artist(self, a):
- self._artist_list.append(a)
-
- def get_size(self, renderer):
- rel_size = 0.
- extent_list = [
- getattr(a.get_window_extent(renderer), self._w_or_h) / a.figure.dpi
- for a in self._artist_list]
- abs_size = max(extent_list, default=0)
- return rel_size, abs_size
-
-
-class MaxWidth(MaxExtent):
- """
- Size whose absolute part is the largest width of the given *artist_list*.
- """
-
- def __init__(self, artist_list):
- super().__init__(artist_list, "width")
-
-
-class MaxHeight(MaxExtent):
- """
- Size whose absolute part is the largest height of the given *artist_list*.
- """
-
- def __init__(self, artist_list):
- super().__init__(artist_list, "height")
-
-
-class Fraction(_Base):
- """
- An instance whose size is a *fraction* of the *ref_size*.
-
- >>> s = Fraction(0.3, AxesX(ax))
- """
-
- def __init__(self, fraction, ref_size):
- _api.check_isinstance(Real, fraction=fraction)
- self._fraction_ref = ref_size
- self._fraction = fraction
-
- def get_size(self, renderer):
- if self._fraction_ref is None:
- return self._fraction, 0.
- else:
- r, a = self._fraction_ref.get_size(renderer)
- rel_size = r*self._fraction
- abs_size = a*self._fraction
- return rel_size, abs_size
-
-
-def from_any(size, fraction_ref=None):
- """
- Create a Fixed unit when the first argument is a float, or a
- Fraction unit if that is a string that ends with %. The second
- argument is only meaningful when Fraction unit is created.
-
- >>> from mpl_toolkits.axes_grid1.axes_size import from_any
- >>> a = from_any(1.2) # => Fixed(1.2)
- >>> from_any("50%", a) # => Fraction(0.5, a)
- """
- if isinstance(size, Real):
- return Fixed(size)
- elif isinstance(size, str):
- if size[-1] == "%":
- return Fraction(float(size[:-1]) / 100, fraction_ref)
- raise ValueError("Unknown format")
-
-
-class _AxesDecorationsSize(_Base):
- """
- Fixed size, corresponding to the size of decorations on a given Axes side.
- """
-
- _get_size_map = {
- "left": lambda tight_bb, axes_bb: axes_bb.xmin - tight_bb.xmin,
- "right": lambda tight_bb, axes_bb: tight_bb.xmax - axes_bb.xmax,
- "bottom": lambda tight_bb, axes_bb: axes_bb.ymin - tight_bb.ymin,
- "top": lambda tight_bb, axes_bb: tight_bb.ymax - axes_bb.ymax,
- }
-
- def __init__(self, ax, direction):
- self._get_size = _api.check_getitem(
- self._get_size_map, direction=direction)
- self._ax_list = [ax] if isinstance(ax, Axes) else ax
-
- def get_size(self, renderer):
- sz = max([
- self._get_size(ax.get_tightbbox(renderer, call_axes_locator=False),
- ax.bbox)
- for ax in self._ax_list])
- dpi = renderer.points_to_pixels(72)
- abs_size = sz / dpi
- rel_size = 0
- return rel_size, abs_size
diff --git a/contrib/python/matplotlib/py3/mpl_toolkits/axes_grid1/inset_locator.py b/contrib/python/matplotlib/py3/mpl_toolkits/axes_grid1/inset_locator.py
deleted file mode 100644
index 6d591a45311..00000000000
--- a/contrib/python/matplotlib/py3/mpl_toolkits/axes_grid1/inset_locator.py
+++ /dev/null
@@ -1,561 +0,0 @@
-"""
-A collection of functions and objects for creating or placing inset axes.
-"""
-
-from matplotlib import _api, _docstring
-from matplotlib.offsetbox import AnchoredOffsetbox
-from matplotlib.patches import Patch, Rectangle
-from matplotlib.path import Path
-from matplotlib.transforms import Bbox, BboxTransformTo
-from matplotlib.transforms import IdentityTransform, TransformedBbox
-
-from . import axes_size as Size
-from .parasite_axes import HostAxes
-
-
-@_api.deprecated("3.8", alternative="Axes.inset_axes")
-class InsetPosition:
- @_docstring.dedent_interpd
- def __init__(self, parent, lbwh):
- """
- An object for positioning an inset axes.
-
- This is created by specifying the normalized coordinates in the axes,
- instead of the figure.
-
- Parameters
- ----------
- parent : `~matplotlib.axes.Axes`
- Axes to use for normalizing coordinates.
-
- lbwh : iterable of four floats
- The left edge, bottom edge, width, and height of the inset axes, in
- units of the normalized coordinate of the *parent* axes.
-
- See Also
- --------
- :meth:`matplotlib.axes.Axes.set_axes_locator`
-
- Examples
- --------
- The following bounds the inset axes to a box with 20%% of the parent
- axes height and 40%% of the width. The size of the axes specified
- ([0, 0, 1, 1]) ensures that the axes completely fills the bounding box:
-
- >>> parent_axes = plt.gca()
- >>> ax_ins = plt.axes([0, 0, 1, 1])
- >>> ip = InsetPosition(parent_axes, [0.5, 0.1, 0.4, 0.2])
- >>> ax_ins.set_axes_locator(ip)
- """
- self.parent = parent
- self.lbwh = lbwh
-
- def __call__(self, ax, renderer):
- bbox_parent = self.parent.get_position(original=False)
- trans = BboxTransformTo(bbox_parent)
- bbox_inset = Bbox.from_bounds(*self.lbwh)
- bb = TransformedBbox(bbox_inset, trans)
- return bb
-
-
-class AnchoredLocatorBase(AnchoredOffsetbox):
- def __init__(self, bbox_to_anchor, offsetbox, loc,
- borderpad=0.5, bbox_transform=None):
- super().__init__(
- loc, pad=0., child=None, borderpad=borderpad,
- bbox_to_anchor=bbox_to_anchor, bbox_transform=bbox_transform
- )
-
- def draw(self, renderer):
- raise RuntimeError("No draw method should be called")
-
- def __call__(self, ax, renderer):
- if renderer is None:
- renderer = ax.figure._get_renderer()
- self.axes = ax
- bbox = self.get_window_extent(renderer)
- px, py = self.get_offset(bbox.width, bbox.height, 0, 0, renderer)
- bbox_canvas = Bbox.from_bounds(px, py, bbox.width, bbox.height)
- tr = ax.figure.transSubfigure.inverted()
- return TransformedBbox(bbox_canvas, tr)
-
-
-class AnchoredSizeLocator(AnchoredLocatorBase):
- def __init__(self, bbox_to_anchor, x_size, y_size, loc,
- borderpad=0.5, bbox_transform=None):
- super().__init__(
- bbox_to_anchor, None, loc,
- borderpad=borderpad, bbox_transform=bbox_transform
- )
-
- self.x_size = Size.from_any(x_size)
- self.y_size = Size.from_any(y_size)
-
- def get_bbox(self, renderer):
- bbox = self.get_bbox_to_anchor()
- dpi = renderer.points_to_pixels(72.)
-
- r, a = self.x_size.get_size(renderer)
- width = bbox.width * r + a * dpi
- r, a = self.y_size.get_size(renderer)
- height = bbox.height * r + a * dpi
-
- fontsize = renderer.points_to_pixels(self.prop.get_size_in_points())
- pad = self.pad * fontsize
-
- return Bbox.from_bounds(0, 0, width, height).padded(pad)
-
-
-class AnchoredZoomLocator(AnchoredLocatorBase):
- def __init__(self, parent_axes, zoom, loc,
- borderpad=0.5,
- bbox_to_anchor=None,
- bbox_transform=None):
- self.parent_axes = parent_axes
- self.zoom = zoom
- if bbox_to_anchor is None:
- bbox_to_anchor = parent_axes.bbox
- super().__init__(
- bbox_to_anchor, None, loc, borderpad=borderpad,
- bbox_transform=bbox_transform)
-
- def get_bbox(self, renderer):
- bb = self.parent_axes.transData.transform_bbox(self.axes.viewLim)
- fontsize = renderer.points_to_pixels(self.prop.get_size_in_points())
- pad = self.pad * fontsize
- return (
- Bbox.from_bounds(
- 0, 0, abs(bb.width * self.zoom), abs(bb.height * self.zoom))
- .padded(pad))
-
-
-class BboxPatch(Patch):
- @_docstring.dedent_interpd
- def __init__(self, bbox, **kwargs):
- """
- Patch showing the shape bounded by a Bbox.
-
- Parameters
- ----------
- bbox : `~matplotlib.transforms.Bbox`
- Bbox to use for the extents of this patch.
-
- **kwargs
- Patch properties. Valid arguments include:
-
- %(Patch:kwdoc)s
- """
- if "transform" in kwargs:
- raise ValueError("transform should not be set")
-
- kwargs["transform"] = IdentityTransform()
- super().__init__(**kwargs)
- self.bbox = bbox
-
- def get_path(self):
- # docstring inherited
- x0, y0, x1, y1 = self.bbox.extents
- return Path._create_closed([(x0, y0), (x1, y0), (x1, y1), (x0, y1)])
-
-
-class BboxConnector(Patch):
- @staticmethod
- def get_bbox_edge_pos(bbox, loc):
- """
- Return the ``(x, y)`` coordinates of corner *loc* of *bbox*; parameters
- behave as documented for the `.BboxConnector` constructor.
- """
- x0, y0, x1, y1 = bbox.extents
- if loc == 1:
- return x1, y1
- elif loc == 2:
- return x0, y1
- elif loc == 3:
- return x0, y0
- elif loc == 4:
- return x1, y0
-
- @staticmethod
- def connect_bbox(bbox1, bbox2, loc1, loc2=None):
- """
- Construct a `.Path` connecting corner *loc1* of *bbox1* to corner
- *loc2* of *bbox2*, where parameters behave as documented as for the
- `.BboxConnector` constructor.
- """
- if isinstance(bbox1, Rectangle):
- bbox1 = TransformedBbox(Bbox.unit(), bbox1.get_transform())
- if isinstance(bbox2, Rectangle):
- bbox2 = TransformedBbox(Bbox.unit(), bbox2.get_transform())
- if loc2 is None:
- loc2 = loc1
- x1, y1 = BboxConnector.get_bbox_edge_pos(bbox1, loc1)
- x2, y2 = BboxConnector.get_bbox_edge_pos(bbox2, loc2)
- return Path([[x1, y1], [x2, y2]])
-
- @_docstring.dedent_interpd
- def __init__(self, bbox1, bbox2, loc1, loc2=None, **kwargs):
- """
- Connect two bboxes with a straight line.
-
- Parameters
- ----------
- bbox1, bbox2 : `~matplotlib.transforms.Bbox`
- Bounding boxes to connect.
-
- loc1, loc2 : {1, 2, 3, 4}
- Corner of *bbox1* and *bbox2* to draw the line. Valid values are::
-
- 'upper right' : 1,
- 'upper left' : 2,
- 'lower left' : 3,
- 'lower right' : 4
-
- *loc2* is optional and defaults to *loc1*.
-
- **kwargs
- Patch properties for the line drawn. Valid arguments include:
-
- %(Patch:kwdoc)s
- """
- if "transform" in kwargs:
- raise ValueError("transform should not be set")
-
- kwargs["transform"] = IdentityTransform()
- kwargs.setdefault(
- "fill", bool({'fc', 'facecolor', 'color'}.intersection(kwargs)))
- super().__init__(**kwargs)
- self.bbox1 = bbox1
- self.bbox2 = bbox2
- self.loc1 = loc1
- self.loc2 = loc2
-
- def get_path(self):
- # docstring inherited
- return self.connect_bbox(self.bbox1, self.bbox2,
- self.loc1, self.loc2)
-
-
-class BboxConnectorPatch(BboxConnector):
- @_docstring.dedent_interpd
- def __init__(self, bbox1, bbox2, loc1a, loc2a, loc1b, loc2b, **kwargs):
- """
- Connect two bboxes with a quadrilateral.
-
- The quadrilateral is specified by two lines that start and end at
- corners of the bboxes. The four sides of the quadrilateral are defined
- by the two lines given, the line between the two corners specified in
- *bbox1* and the line between the two corners specified in *bbox2*.
-
- Parameters
- ----------
- bbox1, bbox2 : `~matplotlib.transforms.Bbox`
- Bounding boxes to connect.
-
- loc1a, loc2a, loc1b, loc2b : {1, 2, 3, 4}
- The first line connects corners *loc1a* of *bbox1* and *loc2a* of
- *bbox2*; the second line connects corners *loc1b* of *bbox1* and
- *loc2b* of *bbox2*. Valid values are::
-
- 'upper right' : 1,
- 'upper left' : 2,
- 'lower left' : 3,
- 'lower right' : 4
-
- **kwargs
- Patch properties for the line drawn:
-
- %(Patch:kwdoc)s
- """
- if "transform" in kwargs:
- raise ValueError("transform should not be set")
- super().__init__(bbox1, bbox2, loc1a, loc2a, **kwargs)
- self.loc1b = loc1b
- self.loc2b = loc2b
-
- def get_path(self):
- # docstring inherited
- path1 = self.connect_bbox(self.bbox1, self.bbox2, self.loc1, self.loc2)
- path2 = self.connect_bbox(self.bbox2, self.bbox1,
- self.loc2b, self.loc1b)
- path_merged = [*path1.vertices, *path2.vertices, path1.vertices[0]]
- return Path(path_merged)
-
-
-def _add_inset_axes(parent_axes, axes_class, axes_kwargs, axes_locator):
- """Helper function to add an inset axes and disable navigation in it."""
- if axes_class is None:
- axes_class = HostAxes
- if axes_kwargs is None:
- axes_kwargs = {}
- inset_axes = axes_class(
- parent_axes.figure, parent_axes.get_position(),
- **{"navigate": False, **axes_kwargs, "axes_locator": axes_locator})
- return parent_axes.figure.add_axes(inset_axes)
-
-
-@_docstring.dedent_interpd
-def inset_axes(parent_axes, width, height, loc='upper right',
- bbox_to_anchor=None, bbox_transform=None,
- axes_class=None, axes_kwargs=None,
- borderpad=0.5):
- """
- Create an inset axes with a given width and height.
-
- Both sizes used can be specified either in inches or percentage.
- For example,::
-
- inset_axes(parent_axes, width='40%%', height='30%%', loc='lower left')
-
- creates in inset axes in the lower left corner of *parent_axes* which spans
- over 30%% in height and 40%% in width of the *parent_axes*. Since the usage
- of `.inset_axes` may become slightly tricky when exceeding such standard
- cases, it is recommended to read :doc:`the examples
- </gallery/axes_grid1/inset_locator_demo>`.
-
- Notes
- -----
- The meaning of *bbox_to_anchor* and *bbox_to_transform* is interpreted
- differently from that of legend. The value of bbox_to_anchor
- (or the return value of its get_points method; the default is
- *parent_axes.bbox*) is transformed by the bbox_transform (the default
- is Identity transform) and then interpreted as points in the pixel
- coordinate (which is dpi dependent).
-
- Thus, following three calls are identical and creates an inset axes
- with respect to the *parent_axes*::
-
- axins = inset_axes(parent_axes, "30%%", "40%%")
- axins = inset_axes(parent_axes, "30%%", "40%%",
- bbox_to_anchor=parent_axes.bbox)
- axins = inset_axes(parent_axes, "30%%", "40%%",
- bbox_to_anchor=(0, 0, 1, 1),
- bbox_transform=parent_axes.transAxes)
-
- Parameters
- ----------
- parent_axes : `matplotlib.axes.Axes`
- Axes to place the inset axes.
-
- width, height : float or str
- Size of the inset axes to create. If a float is provided, it is
- the size in inches, e.g. *width=1.3*. If a string is provided, it is
- the size in relative units, e.g. *width='40%%'*. By default, i.e. if
- neither *bbox_to_anchor* nor *bbox_transform* are specified, those
- are relative to the parent_axes. Otherwise, they are to be understood
- relative to the bounding box provided via *bbox_to_anchor*.
-
- loc : str, default: 'upper right'
- Location to place the inset axes. Valid locations are
- 'upper left', 'upper center', 'upper right',
- 'center left', 'center', 'center right',
- 'lower left', 'lower center', 'lower right'.
- For backward compatibility, numeric values are accepted as well.
- See the parameter *loc* of `.Legend` for details.
-
- bbox_to_anchor : tuple or `~matplotlib.transforms.BboxBase`, optional
- Bbox that the inset axes will be anchored to. If None,
- a tuple of (0, 0, 1, 1) is used if *bbox_transform* is set
- to *parent_axes.transAxes* or *parent_axes.figure.transFigure*.
- Otherwise, *parent_axes.bbox* is used. If a tuple, can be either
- [left, bottom, width, height], or [left, bottom].
- If the kwargs *width* and/or *height* are specified in relative units,
- the 2-tuple [left, bottom] cannot be used. Note that,
- unless *bbox_transform* is set, the units of the bounding box
- are interpreted in the pixel coordinate. When using *bbox_to_anchor*
- with tuple, it almost always makes sense to also specify
- a *bbox_transform*. This might often be the axes transform
- *parent_axes.transAxes*.
-
- bbox_transform : `~matplotlib.transforms.Transform`, optional
- Transformation for the bbox that contains the inset axes.
- If None, a `.transforms.IdentityTransform` is used. The value
- of *bbox_to_anchor* (or the return value of its get_points method)
- is transformed by the *bbox_transform* and then interpreted
- as points in the pixel coordinate (which is dpi dependent).
- You may provide *bbox_to_anchor* in some normalized coordinate,
- and give an appropriate transform (e.g., *parent_axes.transAxes*).
-
- axes_class : `~matplotlib.axes.Axes` type, default: `.HostAxes`
- The type of the newly created inset axes.
-
- axes_kwargs : dict, optional
- Keyword arguments to pass to the constructor of the inset axes.
- Valid arguments include:
-
- %(Axes:kwdoc)s
-
- borderpad : float, default: 0.5
- Padding between inset axes and the bbox_to_anchor.
- The units are axes font size, i.e. for a default font size of 10 points
- *borderpad = 0.5* is equivalent to a padding of 5 points.
-
- Returns
- -------
- inset_axes : *axes_class*
- Inset axes object created.
- """
-
- if (bbox_transform in [parent_axes.transAxes, parent_axes.figure.transFigure]
- and bbox_to_anchor is None):
- _api.warn_external("Using the axes or figure transform requires a "
- "bounding box in the respective coordinates. "
- "Using bbox_to_anchor=(0, 0, 1, 1) now.")
- bbox_to_anchor = (0, 0, 1, 1)
- if bbox_to_anchor is None:
- bbox_to_anchor = parent_axes.bbox
- if (isinstance(bbox_to_anchor, tuple) and
- (isinstance(width, str) or isinstance(height, str))):
- if len(bbox_to_anchor) != 4:
- raise ValueError("Using relative units for width or height "
- "requires to provide a 4-tuple or a "
- "`Bbox` instance to `bbox_to_anchor.")
- return _add_inset_axes(
- parent_axes, axes_class, axes_kwargs,
- AnchoredSizeLocator(
- bbox_to_anchor, width, height, loc=loc,
- bbox_transform=bbox_transform, borderpad=borderpad))
-
-
-@_docstring.dedent_interpd
-def zoomed_inset_axes(parent_axes, zoom, loc='upper right',
- bbox_to_anchor=None, bbox_transform=None,
- axes_class=None, axes_kwargs=None,
- borderpad=0.5):
- """
- Create an anchored inset axes by scaling a parent axes. For usage, also see
- :doc:`the examples </gallery/axes_grid1/inset_locator_demo2>`.
-
- Parameters
- ----------
- parent_axes : `~matplotlib.axes.Axes`
- Axes to place the inset axes.
-
- zoom : float
- Scaling factor of the data axes. *zoom* > 1 will enlarge the
- coordinates (i.e., "zoomed in"), while *zoom* < 1 will shrink the
- coordinates (i.e., "zoomed out").
-
- loc : str, default: 'upper right'
- Location to place the inset axes. Valid locations are
- 'upper left', 'upper center', 'upper right',
- 'center left', 'center', 'center right',
- 'lower left', 'lower center', 'lower right'.
- For backward compatibility, numeric values are accepted as well.
- See the parameter *loc* of `.Legend` for details.
-
- bbox_to_anchor : tuple or `~matplotlib.transforms.BboxBase`, optional
- Bbox that the inset axes will be anchored to. If None,
- *parent_axes.bbox* is used. If a tuple, can be either
- [left, bottom, width, height], or [left, bottom].
- If the kwargs *width* and/or *height* are specified in relative units,
- the 2-tuple [left, bottom] cannot be used. Note that
- the units of the bounding box are determined through the transform
- in use. When using *bbox_to_anchor* it almost always makes sense to
- also specify a *bbox_transform*. This might often be the axes transform
- *parent_axes.transAxes*.
-
- bbox_transform : `~matplotlib.transforms.Transform`, optional
- Transformation for the bbox that contains the inset axes.
- If None, a `.transforms.IdentityTransform` is used (i.e. pixel
- coordinates). This is useful when not providing any argument to
- *bbox_to_anchor*. When using *bbox_to_anchor* it almost always makes
- sense to also specify a *bbox_transform*. This might often be the
- axes transform *parent_axes.transAxes*. Inversely, when specifying
- the axes- or figure-transform here, be aware that not specifying
- *bbox_to_anchor* will use *parent_axes.bbox*, the units of which are
- in display (pixel) coordinates.
-
- axes_class : `~matplotlib.axes.Axes` type, default: `.HostAxes`
- The type of the newly created inset axes.
-
- axes_kwargs : dict, optional
- Keyword arguments to pass to the constructor of the inset axes.
- Valid arguments include:
-
- %(Axes:kwdoc)s
-
- borderpad : float, default: 0.5
- Padding between inset axes and the bbox_to_anchor.
- The units are axes font size, i.e. for a default font size of 10 points
- *borderpad = 0.5* is equivalent to a padding of 5 points.
-
- Returns
- -------
- inset_axes : *axes_class*
- Inset axes object created.
- """
-
- return _add_inset_axes(
- parent_axes, axes_class, axes_kwargs,
- AnchoredZoomLocator(
- parent_axes, zoom=zoom, loc=loc,
- bbox_to_anchor=bbox_to_anchor, bbox_transform=bbox_transform,
- borderpad=borderpad))
-
-
-class _TransformedBboxWithCallback(TransformedBbox):
- """
- Variant of `.TransformBbox` which calls *callback* before returning points.
-
- Used by `.mark_inset` to unstale the parent axes' viewlim as needed.
- """
-
- def __init__(self, *args, callback, **kwargs):
- super().__init__(*args, **kwargs)
- self._callback = callback
-
- def get_points(self):
- self._callback()
- return super().get_points()
-
-
-@_docstring.dedent_interpd
-def mark_inset(parent_axes, inset_axes, loc1, loc2, **kwargs):
- """
- Draw a box to mark the location of an area represented by an inset axes.
-
- This function draws a box in *parent_axes* at the bounding box of
- *inset_axes*, and shows a connection with the inset axes by drawing lines
- at the corners, giving a "zoomed in" effect.
-
- Parameters
- ----------
- parent_axes : `~matplotlib.axes.Axes`
- Axes which contains the area of the inset axes.
-
- inset_axes : `~matplotlib.axes.Axes`
- The inset axes.
-
- loc1, loc2 : {1, 2, 3, 4}
- Corners to use for connecting the inset axes and the area in the
- parent axes.
-
- **kwargs
- Patch properties for the lines and box drawn:
-
- %(Patch:kwdoc)s
-
- Returns
- -------
- pp : `~matplotlib.patches.Patch`
- The patch drawn to represent the area of the inset axes.
-
- p1, p2 : `~matplotlib.patches.Patch`
- The patches connecting two corners of the inset axes and its area.
- """
- rect = _TransformedBboxWithCallback(
- inset_axes.viewLim, parent_axes.transData,
- callback=parent_axes._unstale_viewLim)
-
- kwargs.setdefault("fill", bool({'fc', 'facecolor', 'color'}.intersection(kwargs)))
- pp = BboxPatch(rect, **kwargs)
- parent_axes.add_patch(pp)
-
- p1 = BboxConnector(inset_axes.bbox, rect, loc1=loc1, **kwargs)
- inset_axes.add_patch(p1)
- p1.set_clip_on(False)
- p2 = BboxConnector(inset_axes.bbox, rect, loc1=loc2, **kwargs)
- inset_axes.add_patch(p2)
- p2.set_clip_on(False)
-
- return pp, p1, p2
diff --git a/contrib/python/matplotlib/py3/mpl_toolkits/axes_grid1/mpl_axes.py b/contrib/python/matplotlib/py3/mpl_toolkits/axes_grid1/mpl_axes.py
deleted file mode 100644
index 51c8748758c..00000000000
--- a/contrib/python/matplotlib/py3/mpl_toolkits/axes_grid1/mpl_axes.py
+++ /dev/null
@@ -1,128 +0,0 @@
-import matplotlib.axes as maxes
-from matplotlib.artist import Artist
-from matplotlib.axis import XAxis, YAxis
-
-
-class SimpleChainedObjects:
- def __init__(self, objects):
- self._objects = objects
-
- def __getattr__(self, k):
- _a = SimpleChainedObjects([getattr(a, k) for a in self._objects])
- return _a
-
- def __call__(self, *args, **kwargs):
- for m in self._objects:
- m(*args, **kwargs)
-
-
-class Axes(maxes.Axes):
-
- class AxisDict(dict):
- def __init__(self, axes):
- self.axes = axes
- super().__init__()
-
- def __getitem__(self, k):
- if isinstance(k, tuple):
- r = SimpleChainedObjects(
- # super() within a list comprehension needs explicit args.
- [super(Axes.AxisDict, self).__getitem__(k1) for k1 in k])
- return r
- elif isinstance(k, slice):
- if k.start is None and k.stop is None and k.step is None:
- return SimpleChainedObjects(list(self.values()))
- else:
- raise ValueError("Unsupported slice")
- else:
- return dict.__getitem__(self, k)
-
- def __call__(self, *v, **kwargs):
- return maxes.Axes.axis(self.axes, *v, **kwargs)
-
- @property
- def axis(self):
- return self._axislines
-
- def clear(self):
- # docstring inherited
- super().clear()
- # Init axis artists.
- self._axislines = self.AxisDict(self)
- self._axislines.update(
- bottom=SimpleAxisArtist(self.xaxis, 1, self.spines["bottom"]),
- top=SimpleAxisArtist(self.xaxis, 2, self.spines["top"]),
- left=SimpleAxisArtist(self.yaxis, 1, self.spines["left"]),
- right=SimpleAxisArtist(self.yaxis, 2, self.spines["right"]))
-
-
-class SimpleAxisArtist(Artist):
- def __init__(self, axis, axisnum, spine):
- self._axis = axis
- self._axisnum = axisnum
- self.line = spine
-
- if isinstance(axis, XAxis):
- self._axis_direction = ["bottom", "top"][axisnum-1]
- elif isinstance(axis, YAxis):
- self._axis_direction = ["left", "right"][axisnum-1]
- else:
- raise ValueError(
- f"axis must be instance of XAxis or YAxis, but got {axis}")
- super().__init__()
-
- @property
- def major_ticks(self):
- tickline = "tick%dline" % self._axisnum
- return SimpleChainedObjects([getattr(tick, tickline)
- for tick in self._axis.get_major_ticks()])
-
- @property
- def major_ticklabels(self):
- label = "label%d" % self._axisnum
- return SimpleChainedObjects([getattr(tick, label)
- for tick in self._axis.get_major_ticks()])
-
- @property
- def label(self):
- return self._axis.label
-
- def set_visible(self, b):
- self.toggle(all=b)
- self.line.set_visible(b)
- self._axis.set_visible(True)
- super().set_visible(b)
-
- def set_label(self, txt):
- self._axis.set_label_text(txt)
-
- def toggle(self, all=None, ticks=None, ticklabels=None, label=None):
-
- if all:
- _ticks, _ticklabels, _label = True, True, True
- elif all is not None:
- _ticks, _ticklabels, _label = False, False, False
- else:
- _ticks, _ticklabels, _label = None, None, None
-
- if ticks is not None:
- _ticks = ticks
- if ticklabels is not None:
- _ticklabels = ticklabels
- if label is not None:
- _label = label
-
- if _ticks is not None:
- tickparam = {f"tick{self._axisnum}On": _ticks}
- self._axis.set_tick_params(**tickparam)
- if _ticklabels is not None:
- tickparam = {f"label{self._axisnum}On": _ticklabels}
- self._axis.set_tick_params(**tickparam)
-
- if _label is not None:
- pos = self._axis.get_label_position()
- if (pos == self._axis_direction) and not _label:
- self._axis.label.set_visible(False)
- elif _label:
- self._axis.label.set_visible(True)
- self._axis.set_label_position(self._axis_direction)
diff --git a/contrib/python/matplotlib/py3/mpl_toolkits/axes_grid1/parasite_axes.py b/contrib/python/matplotlib/py3/mpl_toolkits/axes_grid1/parasite_axes.py
deleted file mode 100644
index 2a2b5957e84..00000000000
--- a/contrib/python/matplotlib/py3/mpl_toolkits/axes_grid1/parasite_axes.py
+++ /dev/null
@@ -1,257 +0,0 @@
-from matplotlib import _api, cbook
-import matplotlib.artist as martist
-import matplotlib.transforms as mtransforms
-from matplotlib.transforms import Bbox
-from .mpl_axes import Axes
-
-
-class ParasiteAxesBase:
-
- def __init__(self, parent_axes, aux_transform=None,
- *, viewlim_mode=None, **kwargs):
- self._parent_axes = parent_axes
- self.transAux = aux_transform
- self.set_viewlim_mode(viewlim_mode)
- kwargs["frameon"] = False
- super().__init__(parent_axes.figure, parent_axes._position, **kwargs)
-
- def clear(self):
- super().clear()
- martist.setp(self.get_children(), visible=False)
- self._get_lines = self._parent_axes._get_lines
- self._parent_axes.callbacks._connect_picklable(
- "xlim_changed", self._sync_lims)
- self._parent_axes.callbacks._connect_picklable(
- "ylim_changed", self._sync_lims)
-
- def pick(self, mouseevent):
- # This most likely goes to Artist.pick (depending on axes_class given
- # to the factory), which only handles pick events registered on the
- # axes associated with each child:
- super().pick(mouseevent)
- # But parasite axes are additionally given pick events from their host
- # axes (cf. HostAxesBase.pick), which we handle here:
- for a in self.get_children():
- if (hasattr(mouseevent.inaxes, "parasites")
- and self in mouseevent.inaxes.parasites):
- a.pick(mouseevent)
-
- # aux_transform support
-
- def _set_lim_and_transforms(self):
- if self.transAux is not None:
- self.transAxes = self._parent_axes.transAxes
- self.transData = self.transAux + self._parent_axes.transData
- self._xaxis_transform = mtransforms.blended_transform_factory(
- self.transData, self.transAxes)
- self._yaxis_transform = mtransforms.blended_transform_factory(
- self.transAxes, self.transData)
- else:
- super()._set_lim_and_transforms()
-
- def set_viewlim_mode(self, mode):
- _api.check_in_list([None, "equal", "transform"], mode=mode)
- self._viewlim_mode = mode
-
- def get_viewlim_mode(self):
- return self._viewlim_mode
-
- def _sync_lims(self, parent):
- viewlim = parent.viewLim.frozen()
- mode = self.get_viewlim_mode()
- if mode is None:
- pass
- elif mode == "equal":
- self.viewLim.set(viewlim)
- elif mode == "transform":
- self.viewLim.set(viewlim.transformed(self.transAux.inverted()))
- else:
- _api.check_in_list([None, "equal", "transform"], mode=mode)
-
- # end of aux_transform support
-
-
-parasite_axes_class_factory = cbook._make_class_factory(
- ParasiteAxesBase, "{}Parasite")
-ParasiteAxes = parasite_axes_class_factory(Axes)
-
-
-class HostAxesBase:
- def __init__(self, *args, **kwargs):
- self.parasites = []
- super().__init__(*args, **kwargs)
-
- def get_aux_axes(
- self, tr=None, viewlim_mode="equal", axes_class=None, **kwargs):
- """
- Add a parasite axes to this host.
-
- Despite this method's name, this should actually be thought of as an
- ``add_parasite_axes`` method.
-
- .. versionchanged:: 3.7
- Defaults to same base axes class as host axes.
-
- Parameters
- ----------
- tr : `~matplotlib.transforms.Transform` or None, default: None
- If a `.Transform`, the following relation will hold:
- ``parasite.transData = tr + host.transData``.
- If None, the parasite's and the host's ``transData`` are unrelated.
- viewlim_mode : {"equal", "transform", None}, default: "equal"
- How the parasite's view limits are set: directly equal to the
- parent axes ("equal"), equal after application of *tr*
- ("transform"), or independently (None).
- axes_class : subclass type of `~matplotlib.axes.Axes`, optional
- The `~.axes.Axes` subclass that is instantiated. If None, the base
- class of the host axes is used.
- **kwargs
- Other parameters are forwarded to the parasite axes constructor.
- """
- if axes_class is None:
- axes_class = self._base_axes_class
- parasite_axes_class = parasite_axes_class_factory(axes_class)
- ax2 = parasite_axes_class(
- self, tr, viewlim_mode=viewlim_mode, **kwargs)
- # note that ax2.transData == tr + ax1.transData
- # Anything you draw in ax2 will match the ticks and grids of ax1.
- self.parasites.append(ax2)
- ax2._remove_method = self.parasites.remove
- return ax2
-
- def draw(self, renderer):
- orig_children_len = len(self._children)
-
- locator = self.get_axes_locator()
- if locator:
- pos = locator(self, renderer)
- self.set_position(pos, which="active")
- self.apply_aspect(pos)
- else:
- self.apply_aspect()
-
- rect = self.get_position()
- for ax in self.parasites:
- ax.apply_aspect(rect)
- self._children.extend(ax.get_children())
-
- super().draw(renderer)
- del self._children[orig_children_len:]
-
- def clear(self):
- super().clear()
- for ax in self.parasites:
- ax.clear()
-
- def pick(self, mouseevent):
- super().pick(mouseevent)
- # Also pass pick events on to parasite axes and, in turn, their
- # children (cf. ParasiteAxesBase.pick)
- for a in self.parasites:
- a.pick(mouseevent)
-
- def twinx(self, axes_class=None):
- """
- Create a twin of Axes with a shared x-axis but independent y-axis.
-
- The y-axis of self will have ticks on the left and the returned axes
- will have ticks on the right.
- """
- ax = self._add_twin_axes(axes_class, sharex=self)
- self.axis["right"].set_visible(False)
- ax.axis["right"].set_visible(True)
- ax.axis["left", "top", "bottom"].set_visible(False)
- return ax
-
- def twiny(self, axes_class=None):
- """
- Create a twin of Axes with a shared y-axis but independent x-axis.
-
- The x-axis of self will have ticks on the bottom and the returned axes
- will have ticks on the top.
- """
- ax = self._add_twin_axes(axes_class, sharey=self)
- self.axis["top"].set_visible(False)
- ax.axis["top"].set_visible(True)
- ax.axis["left", "right", "bottom"].set_visible(False)
- return ax
-
- def twin(self, aux_trans=None, axes_class=None):
- """
- Create a twin of Axes with no shared axis.
-
- While self will have ticks on the left and bottom axis, the returned
- axes will have ticks on the top and right axis.
- """
- if aux_trans is None:
- aux_trans = mtransforms.IdentityTransform()
- ax = self._add_twin_axes(
- axes_class, aux_transform=aux_trans, viewlim_mode="transform")
- self.axis["top", "right"].set_visible(False)
- ax.axis["top", "right"].set_visible(True)
- ax.axis["left", "bottom"].set_visible(False)
- return ax
-
- def _add_twin_axes(self, axes_class, **kwargs):
- """
- Helper for `.twinx`/`.twiny`/`.twin`.
-
- *kwargs* are forwarded to the parasite axes constructor.
- """
- if axes_class is None:
- axes_class = self._base_axes_class
- ax = parasite_axes_class_factory(axes_class)(self, **kwargs)
- self.parasites.append(ax)
- ax._remove_method = self._remove_any_twin
- return ax
-
- def _remove_any_twin(self, ax):
- self.parasites.remove(ax)
- restore = ["top", "right"]
- if ax._sharex:
- restore.remove("top")
- if ax._sharey:
- restore.remove("right")
- self.axis[tuple(restore)].set_visible(True)
- self.axis[tuple(restore)].toggle(ticklabels=False, label=False)
-
- @_api.make_keyword_only("3.8", "call_axes_locator")
- def get_tightbbox(self, renderer=None, call_axes_locator=True,
- bbox_extra_artists=None):
- bbs = [
- *[ax.get_tightbbox(renderer, call_axes_locator=call_axes_locator)
- for ax in self.parasites],
- super().get_tightbbox(renderer,
- call_axes_locator=call_axes_locator,
- bbox_extra_artists=bbox_extra_artists)]
- return Bbox.union([b for b in bbs if b.width != 0 or b.height != 0])
-
-
-host_axes_class_factory = host_subplot_class_factory = \
- cbook._make_class_factory(HostAxesBase, "{}HostAxes", "_base_axes_class")
-HostAxes = SubplotHost = host_axes_class_factory(Axes)
-
-
-def host_axes(*args, axes_class=Axes, figure=None, **kwargs):
- """
- Create axes that can act as a hosts to parasitic axes.
-
- Parameters
- ----------
- figure : `~matplotlib.figure.Figure`
- Figure to which the axes will be added. Defaults to the current figure
- `.pyplot.gcf()`.
-
- *args, **kwargs
- Will be passed on to the underlying `~.axes.Axes` object creation.
- """
- import matplotlib.pyplot as plt
- host_axes_class = host_axes_class_factory(axes_class)
- if figure is None:
- figure = plt.gcf()
- ax = host_axes_class(figure, *args, **kwargs)
- figure.add_axes(ax)
- return ax
-
-
-host_subplot = host_axes