10000 Inset orientation by timhoffm · Pull Request #14686 · matplotlib/matplotlib · GitHub
[go: up one dir, main page]

Skip to content

Inset orientation #14686

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 16, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 40 additions & 40 deletions lib/matplotlib/axes/_axes.py
Original file line number Diff line number Diff line change
Expand Up @@ -423,13 +423,12 @@ def inset_axes(self, bounds, *, transform=None, zorder=5,
parent axes.

**kwargs

Other *kwargs* are passed on to the `axes.Axes` child axes.
Other *kwargs* are passed on to the `~.axes.Axes` child axes.

Returns
-------
Axes
The created `.axes.Axes` instance.
ax
The created `~.axes.Axes` instance.

Examples
--------
Expand Down Expand Up @@ -468,8 +467,7 @@ def indicate_inset(self, bounds, inset_ax=None, *, transform=None,
"""
Add an inset indicator to the axes. This is a rectangle on the plot
at the position indicated by *bounds* that optionally has lines that
connect the rectangle to an inset axes
(`.Axes.inset_axes`).
connect the rectangle to an inset axes (`.Axes.inset_axes`).

Warnings
--------
Expand Down Expand Up @@ -499,10 +497,10 @@ def indicate_inset(self, bounds, inset_ax=None, *, transform=None,
Color of the rectangle and color of the connecting lines. Default
is '0.5'.

alpha : number
alpha : float
Transparency of the rectangle and connector lines. Default is 0.5.

zorder : number
zorder : float
Drawing order of the rectangle and connector lines. Default is 4.99
(just below the default level of inset axes).

Expand All @@ -511,19 +509,16 @@ def indicate_inset(self, bounds, inset_ax=None, *, transform=None,

Returns
-------
rectangle_patch : `.Patches.Rectangle`
Rectangle artist.
rectangle_patch : `.patches.Rectangle`
The indicator frame.

connector_lines : optional 4-tuple of `.Patches.ConnectionPatch`
Each of four connector lines coming from the given rectangle
on this axes in the order lower left, upper left, lower right,
upper right: *None* if *inset_ax* is *None*.
Two are set with visibility to *False*,
but the user can set the visibility to *True* if the
automatic choice is not deemed correct.
connector_lines : 4-tuple of `.patches.ConnectionPatch`
The four connector lines connecting to (lower_left, upper_left,
lower_right upper_right) corners of *inset_ax*. Two lines are
set with visibility to *False*, but the user can set the
visibility to True if the automatic choice is not deemed correct.

"""

# to make the axes connectors work, we need to apply the aspect to
# the parent axes.
self.apply_aspect()
Expand All @@ -532,31 +527,36 @@ def indicate_inset(self, bounds, inset_ax=None, *, transform=None,
transform = self.transData
label = kwargs.pop('label', 'indicate_inset')

xy = (bounds[0], bounds[1])
rectpatch = mpatches.Rectangle(xy, bounds[2], bounds[3],
facecolor=facecolor, edgecolor=edgecolor, alpha=alpha,
zorder=zorder, label=label, transform=transform, **kwargs)
self.add_patch(rectpatch)
x, y, width, height = bounds
rectangle_patch = mpatches.Rectangle(
(x, y), width, height,
facecolor=facecolor, edgecolor=edgecolor, alpha=alpha,
zorder=zorder, label=label, transform=transform, **kwargs)
self.add_patch(rectangle_patch)

connects = []

if inset_ax is not None:
# want to connect the indicator to the rect....
xr = [bounds[0], bounds[0]+bounds[2]]
yr = [bounds[1], bounds[1]+bounds[3]]
for xc in range(2):
for yc in range(2):
xyA = (xc, yc)
xyB = (xr[xc], yr[yc])
connects.append(
mpatches.ConnectionPatch(
xyA, xyB,
'axes fraction', 'data',
axesA=inset_ax, axesB=self, arrowstyle="-",
zorder=zorder, edgecolor=edgecolor, alpha=alpha
)
)
self.add_patch(connects[-1])
# connect the inset_axes to the rectangle
for xy_inset_ax in [(0, 0), (0, 1), (1, 0), (1, 1)]:
# inset_ax positions are in axes coordinates
# The 0, 1 values define the four edges if the inset_ax
# lower_left, upper_left, lower_right upper_right.
ex, ey = xy_inset_ax
if self.xaxis.get_inverted():
ex = 1 - ex
if self.yaxis.get_inverted():
ey = 1 - ey
xy_data = x + ex * width, y + ey * height
p = mpatches.ConnectionPatch(xy_inset_ax, xy_data,
coordsA='axes fraction',
coordsB='data',
axesA=inset_ax, axesB=self,
arrowstyle="-", zorder=zorder,
edgecolor=edgecolor, alpha=alpha)
connects.append(p)
self.add_patch(p)

# decide which two of the lines to keep visible....
pos = inset_ax.get_position()
bboxins = pos.transformed(self.figure.transFigure)
Expand All @@ -572,7 +572,7 @@ def indicate_inset(self, bounds, inset_ax=None, *, transform=None,
connects[2].set_visible(x1 == y0)
connects[3].set_visible(x1 ^ y1)

return rectpatch, tuple(connects) if connects else None
return rectangle_patch, tuple(connects) if connects else None

def indicate_inset_zoom(self, inset_ax, **kwargs):
"""
Expand Down
26 changes: 26 additions & 0 deletions lib/matplotlib/tests/test_axes.py
Original file line number Diff line number Diff line change
Expand Up @@ -6021,6 +6021,32 @@ def test_zoom_inset():
xx, rtol=1e-4)


@pytest.mark.parametrize('x_inverted', [False, True])
@pytest.mark.parametrize('y_inverted', [False, True])
def test_indicate_inset_inverted(x_inverted, y_inverted):
"""
Test that the inset lines are correctly located with inverted data axes.
"""
fig, (ax1, ax2) = plt.subplots(1, 2)

x = np.arange(10)
ax1.plot(x, x, 'o')
if x_inverted:
ax1.invert_xaxis()
if y_inverted:
ax1.invert_yaxis()

rect, bounds = ax1.indicate_inset([2, 2, 5, 4], ax2)
lower_left, upper_left, lower_right, upper_right = bounds

sign_x = -1 if x_inverted else 1
sign_y = -1 if y_inverted else 1
assert sign_x * (lower_right.xy2[0] - lower_left.xy2[0]) > 0
assert sign_x * (upper_right.xy2[0] - upper_left.xy2[0]) > 0
assert sign_y * (upper_left.xy2[1] - lower_left.xy2[1]) > 0
assert sign_y * (upper_right.xy2[1] - lower_right.xy2[1]) > 0


def test_set_position():
fig, ax = plt.subplots()
ax.set_aspect(3.)
Expand Down
0