Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit ea78e25

Browse filesBrowse files
authored
Merge pull request #27996 from rcomer/indicate-inset-patch
Create `InsetIndicator` artist
2 parents fec6863 + b833055 commit ea78e25
Copy full SHA for ea78e25

File tree

13 files changed

+493
-81
lines changed
Filter options

13 files changed

+493
-81
lines changed

‎ci/mypy-stubtest-allowlist.txt

Copy file name to clipboardExpand all lines: ci/mypy-stubtest-allowlist.txt
+3Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,3 +46,6 @@ matplotlib.spines.Spine._T
4646

4747
# Parameter inconsistency due to 3.10 deprecation
4848
matplotlib.figure.FigureBase.get_figure
49+
50+
# getitem method only exists for 3.10 deprecation backcompatability
51+
matplotlib.inset.InsetIndicator.__getitem__

‎doc/api/index.rst

Copy file name to clipboardExpand all lines: doc/api/index.rst
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ Alphabetical list of modules:
104104
gridspec_api.rst
105105
hatch_api.rst
106106
image_api.rst
107+
inset_api.rst
107108
layout_engine_api.rst
108109
legend_api.rst
109110
legend_handler_api.rst

‎doc/api/inset_api.rst

Copy file name to clipboard
+8Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
********************
2+
``matplotlib.inset``
3+
********************
4+
5+
.. automodule:: matplotlib.inset
6+
:members:
7+
:undoc-members:
8+
:show-inheritance:
+8Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
``InsetIndicator`` artist
2+
~~~~~~~~~~~~~~~~~~~~~~~~~
3+
4+
`~.Axes.indicate_inset` and `~.Axes.indicate_inset_zoom` now return an instance
5+
of `~matplotlib.inset.InsetIndicator`. Use the
6+
`~matplotlib.inset.InsetIndicator.rectangle` and
7+
`~matplotlib.inset.InsetIndicator.connectors` properties of this artist to
8+
access the objects that were previously returned directly.
+18Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
``InsetIndicator`` artist
2+
~~~~~~~~~~~~~~~~~~~~~~~~~
3+
4+
`~.Axes.indicate_inset` and `~.Axes.indicate_inset_zoom` now return an instance
5+
of `~matplotlib.inset.InsetIndicator` which contains the rectangle and
6+
connector patches. These patches now update automatically so that
7+
8+
.. code-block:: python
9+
10+
ax.indicate_inset_zoom(ax_inset)
11+
ax_inset.set_xlim(new_lim)
12+
13+
now gives the same result as
14+
15+
.. code-block:: python
16+
17+
ax_inset.set_xlim(new_lim)
18+
ax.indicate_inset_zoom(ax_inset)

‎lib/matplotlib/axes/_axes.py

Copy file name to clipboardExpand all lines: lib/matplotlib/axes/_axes.py
+40-70Lines changed: 40 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import matplotlib.contour as mcontour
1717
import matplotlib.dates # noqa: F401, Register date unit converter as side effect.
1818
import matplotlib.image as mimage
19+
import matplotlib.inset as minset
1920
import matplotlib.legend as mlegend
2021
import matplotlib.lines as mlines
2122
import matplotlib.markers as mmarkers
@@ -419,9 +420,9 @@ def inset_axes(self, bounds, *, transform=None, zorder=5, **kwargs):
419420
return inset_ax
420421

421422
@_docstring.interpd
422-
def indicate_inset(self, bounds, inset_ax=None, *, transform=None,
423+
def indicate_inset(self, bounds=None, inset_ax=None, *, transform=None,
423424
facecolor='none', edgecolor='0.5', alpha=0.5,
424-
zorder=4.99, **kwargs):
425+
zorder=None, **kwargs):
425426
"""
426427
Add an inset indicator to the Axes. This is a rectangle on the plot
427428
at the position indicated by *bounds* that optionally has lines that
@@ -433,18 +434,19 @@ def indicate_inset(self, bounds, inset_ax=None, *, transform=None,
433434
434435
Parameters
435436
----------
436-
bounds : [x0, y0, width, height]
437+
bounds : [x0, y0, width, height], optional
437438
Lower-left corner of rectangle to be marked, and its width
438-
and height.
439+
and height. If not set, the bounds will be calculated from the
440+
data limits of *inset_ax*, which must be supplied.
439441
440-
inset_ax : `.Axes`
442+
inset_ax : `.Axes`, optional
441443
An optional inset Axes to draw connecting lines to. Two lines are
442444
drawn connecting the indicator box to the inset Axes on corners
443445
chosen so as to not overlap with the indicator box.
444446
445447
transform : `.Transform`
446448
Transform for the rectangle coordinates. Defaults to
447-
`ax.transAxes`, i.e. the units of *rect* are in Axes-relative
449+
``ax.transAxes``, i.e. the units of *rect* are in Axes-relative
448450
coordinates.
449451
450452
facecolor : :mpltype:`color`, default: 'none'
@@ -469,15 +471,20 @@ def indicate_inset(self, bounds, inset_ax=None, *, transform=None,
469471
470472
Returns
471473
-------
472-
rectangle_patch : `.patches.Rectangle`
473-
The indicator frame.
474+
inset_indicator : `.inset.InsetIndicator`
475+
An artist which contains
474476
475-
connector_lines : 4-tuple of `.patches.ConnectionPatch`
476-
The four connector lines connecting to (lower_left, upper_left,
477-
lower_right upper_right) corners of *inset_ax*. Two lines are
478-
set with visibility to *False*, but the user can set the
479-
visibility to True if the automatic choice is not deemed correct.
477+
inset_indicator.rectangle : `.Rectangle`
478+
The indicator frame.
480479
480+
inset_indicator.connectors : 4-tuple of `.patches.ConnectionPatch`
481+
The four connector lines connecting to (lower_left, upper_left,
482+
lower_right upper_right) corners of *inset_ax*. Two lines are
483+
set with visibility to *False*, but the user can set the
484+
visibility to True if the automatic choice is not deemed correct.
485+
486+
.. versionchanged:: 3.10
487+
Previously the rectangle and connectors tuple were returned.
481488
"""
482489
# to make the Axes connectors work, we need to apply the aspect to
483490
# the parent Axes.
@@ -487,51 +494,13 @@ def indicate_inset(self, bounds, inset_ax=None, *, transform=None,
487494
transform = self.transData
488495
kwargs.setdefault('label', '_indicate_inset')
489496

490-
x, y, width, height = bounds
491-
rectangle_patch = mpatches.Rectangle(
492-
(x, y), width, height,
497+
indicator_patch = minset.InsetIndicator(
498+
bounds, inset_ax=inset_ax,
493499
facecolor=facecolor, edgecolor=edgecolor, alpha=alpha,
494500
zorder=zorder, transform=transform, **kwargs)
495-
self.add_patch(rectangle_patch)
496-
497-
connects = []
498-
499-
if inset_ax is not None:
500-
# connect the inset_axes to the rectangle
501-
for xy_inset_ax in [(0, 0), (0, 1), (1, 0), (1, 1)]:
502-
# inset_ax positions are in axes coordinates
503-
# The 0, 1 values define the four edges if the inset_ax
504-
# lower_left, upper_left, lower_right upper_right.
505-
ex, ey = xy_inset_ax
506-
if self.xaxis.get_inverted():
507-
ex = 1 - ex
508-
if self.yaxis.get_inverted():
509-
ey = 1 - ey
510-
xy_data = x + ex * width, y + ey * height
511-
p = mpatches.ConnectionPatch(
512-
xyA=xy_inset_ax, coordsA=inset_ax.transAxes,
513-
xyB=xy_data, coordsB=self.transData,
514-
arrowstyle="-", zorder=zorder,
515-
edgecolor=edgecolor, alpha=alpha)
516-
connects.append(p)
517-
self.add_patch(p)
518-
519-
# decide which two of the lines to keep visible....
520-
pos = inset_ax.get_position()
521-
bboxins = pos.transformed(self.get_figure(root=False).transSubfigure)
522-
rectbbox = mtransforms.Bbox.from_bounds(
523-
*bounds
524-
).transformed(transform)
525-
x0 = rectbbox.x0 < bboxins.x0
526-
x1 = rectbbox.x1 < bboxins.x1
527-
y0 = rectbbox.y0 < bboxins.y0
528-
y1 = rectbbox.y1 < bboxins.y1
529-
connects[0].set_visible(x0 ^ y0)
530-
connects[1].set_visible(x0 == y1)
531-
connects[2].set_visible(x1 == y0)
532-
connects[3].set_visible(x1 ^ y1)
533-
534-
return rectangle_patch, tuple(connects) if connects else None
501+
self.add_artist(indicator_patch)
502+
503+
return indicator_patch
535504

536505
def indicate_inset_zoom(self, inset_ax, **kwargs):
537506
"""
@@ -555,22 +524,23 @@ def indicate_inset_zoom(self, inset_ax, **kwargs):
555524
556525
Returns
557526
-------
558-
rectangle_patch : `.patches.Rectangle`
559-
Rectangle artist.
560-
561-
connector_lines : 4-tuple of `.patches.ConnectionPatch`
562-
Each of four connector lines coming from the rectangle drawn on
563-
this axis, in the order lower left, upper left, lower right,
564-
upper right.
565-
Two are set with visibility to *False*, but the user can
566-
set the visibility to *True* if the automatic choice is not deemed
567-
correct.
527+
inset_indicator : `.inset.InsetIndicator`
528+
An artist which contains
529+
530+
inset_indicator.rectangle : `.Rectangle`
531+
The indicator frame.
532+
533+
inset_indicator.connectors : 4-tuple of `.patches.ConnectionPatch`
534+
The four connector lines connecting to (lower_left, upper_left,
535+
lower_right upper_right) corners of *inset_ax*. Two lines are
536+
set with visibility to *False*, but the user can set the
537+
visibility to True if the automatic choice is not deemed correct.
538+
539+
.. versionchanged:: 3.10
540+
Previously the rectangle and connectors tuple were returned.
568541
"""
569542

570-
xlim = inset_ax.get_xlim()
571-
ylim = inset_ax.get_ylim()
572-
rect = (xlim[0], ylim[0], xlim[1] - xlim[0], ylim[1] - ylim[0])
573-
return self.indicate_inset(rect, inset_ax, **kwargs)
543+
return self.indicate_inset(None, inset_ax, **kwargs)
574544

575545
@_docstring.interpd
576546
def secondary_xaxis(self, location, functions=None, *, transform=None, **kwargs):

‎lib/matplotlib/axes/_axes.pyi

Copy file name to clipboardExpand all lines: lib/matplotlib/axes/_axes.pyi
+5-4Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ from matplotlib.colors import Colormap, Normalize
1515
from matplotlib.container import BarContainer, ErrorbarContainer, StemContainer
1616
from matplotlib.contour import ContourSet, QuadContourSet
1717
from matplotlib.image import AxesImage, PcolorImage
18+
from matplotlib.inset import InsetIndicator
1819
from matplotlib.legend import Legend
1920
from matplotlib.legend_handler import HandlerBase
2021
from matplotlib.lines import Line2D, AxLine
@@ -75,17 +76,17 @@ class Axes(_AxesBase):
7576
) -> Axes: ...
7677
def indicate_inset(
7778
self,
78-
bounds: tuple[float, float, float, float],
79+
bounds: tuple[float, float, float, float] | None = ...,
7980
inset_ax: Axes | None = ...,
8081
*,
8182
transform: Transform | None = ...,
8283
facecolor: ColorType = ...,
8384
edgecolor: ColorType = ...,
8485
alpha: float = ...,
85-
zorder: float = ...,
86+
zorder: float | None = ...,
8687
**kwargs
87-
) -> Rectangle: ...
88-
def indicate_inset_zoom(self, inset_ax: Axes, **kwargs) -> Rectangle: ...
88+
) -> InsetIndicator: ...
89+
def indicate_inset_zoom(self, inset_ax: Axes, **kwargs) -> InsetIndicator: ...
8990
def secondary_xaxis(
9091
self,
9192
location: Literal["top", "bottom"] | float,

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.