Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Open
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
32 changes: 32 additions & 0 deletions doc/release/next_whats_new/fig_anchored_offsetbox.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
``AnchoredOffsetbox`` and ``AnchoredText`` for ``Figure`` and ``SubFigure``
---------------------------------------------------------------------------

The `.AnchoredOffsetbox` and `.AnchoredText` artists may now be directly added to a
`.Figure` or `.SubFigure` and by default will be anchored relative to their parent
``(Sub)Figure``.


.. plot::
:include-source: true
:alt: The left half of the figure contains two text boxes with black outlines. One in the top left of the figure reads "Anchored to Figure". One at the bottom and to the left the vertical center line reads "Anchored to SubFigure". A third box containing a blue circle is halfway up and to the right of the vertical center line.

import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
from matplotlib.offsetbox import AnchoredText, AnchoredOffsetbox, DrawingArea

fig = plt.figure()

sfig1, sfig2 = fig.subfigures(ncols=2)
sfig1.set_facecolor("lemonchiffon")
sfig2.set_facecolor("lightcyan")

fig_text = AnchoredText("Anchored to Figure", loc="upper left")
fig.add_artist(fig_text)

sfig_text = AnchoredText("Anchored to SubFigure", loc="lower right")
sfig1.add_artist(sfig_text)

area = DrawingArea(width=30, height=30)
area.add_artist(mpatches.Circle((15, 15), 15, fc="tab:blue"))
box = AnchoredOffsetbox(child=area, loc="center left")
sfig2.add_artist(box)
6 changes: 3 additions & 3 deletions galleries/examples/misc/anchored_artists.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,12 @@
from matplotlib.patches import Circle, Ellipse


def draw_text(ax):
def draw_text(fig):
"""Draw a text-box anchored to the upper-left corner of the figure."""
box = AnchoredOffsetbox(child=TextArea("Figure 1a"),
loc="upper left", frameon=True)
box.patch.set_boxstyle("round,pad=0.,rounding_size=0.2")
ax.add_artist(box)
fig.add_artist(box)


def draw_circles(ax):
Expand Down Expand Up @@ -68,7 +68,7 @@ def draw_sizebar(ax):
fig, ax = plt.subplots()
ax.set_aspect(1)

draw_text(ax)
draw_text(fig)
draw_circles(ax)
draw_ellipse(ax)
draw_sizebar(ax)
Expand Down
15 changes: 10 additions & 5 deletions lib/matplotlib/offsetbox.py
Original file line number Diff line number Diff line change
Expand Up @@ -909,10 +909,14 @@ class AnchoredOffsetbox(OffsetBox):
"""
An OffsetBox placed according to location *loc*.

AnchoredOffsetbox has a single child. When multiple children are needed,
use an extra OffsetBox to enclose them. By default, the offset box is
anchored against its parent Axes. You may explicitly specify the
*bbox_to_anchor*.
AnchoredOffsetbox has a single child. When multiple children are needed, use an
extra OffsetBox to enclose them. By default, the offset box is anchored against its
parent Axes, SubFigure or Figure. You may explicitly specify the *bbox_to_anchor*.

.. versionadded:: 3.12
`.AnchoredOffsetbox` can now be added directly to a `.Figure` or `.SubFigure`,
and will by default be anchored to that parent.

"""
zorder = 5 # zorder of the legend

Expand Down Expand Up @@ -1024,7 +1028,8 @@ def get_bbox(self, renderer):
def get_bbox_to_anchor(self):
"""Return the bbox that the box is anchored to."""
if self._bbox_to_anchor is None:
return self.axes.bbox
return (self.axes.bbox if self.axes is not None else
self.get_figure(root=False).bbox)
else:
transform = self._bbox_to_anchor_transform
if transform is None:
Expand Down
23 changes: 23 additions & 0 deletions lib/matplotlib/tests/test_offsetbox.py
Original file line number Diff line number Diff line change
Expand Up @@ -507,3 +507,26 @@ def test_anchored_offsetbox_tuple_and_float_borderpad():
# in the y-direction.
assert pos_tuple_asym.x0 > pos_float.x0
assert pos_tuple_asym.y0 < pos_float.y0


def test_figure_anchored_offsetbox():
fig = plt.figure()
sfig1, _ = fig.subfigures(ncols=2)

box1 = AnchoredText("wibble", loc="upper left", borderpad=0)
fig.add_artist(box1)

box2 = AnchoredText("meep", loc="lower right", borderpad=0)
sfig1.add_artist(box2)

fig.draw_without_rendering()

# Upper left of figure
tight_bb1 = box1.get_tightbbox()
assert tight_bb1.x0 == pytest.approx(0)
assert tight_bb1.y1 == pytest.approx(480)

# lower right of lefthand subfigure
tight_bb2 = box2.get_tightbbox()
assert tight_bb2.x1 == pytest.approx(320)
assert tight_bb2.y0 == pytest.approx(0)
Loading