Skip to content

Commit ec6df1d

Browse files
Add fig.add_artist method
1 parent 9ec4b95 commit ec6df1d

File tree

3 files changed

+81
-0
lines changed

3 files changed

+81
-0
lines changed
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
Figure has an `~.figure.Figure.add_artist` method
2+
-------------------------------------------------
3+
4+
A method `~.figure.Figure.add_artist` has been added to the
5+
:class:`~.figure.Figure` class, which allows to add artists directly to a
6+
figure. E.g.
7+
8+
::
9+
10+
circ = plt.Circle((.7, .5), .05)
11+
fig.add_artist(circ)
12+
13+
In case the added artist has no transform set previously, it will be set to
14+
the figure transform (``fig.transFigure``).
15+
This new method may be useful for adding artists to figures without axes or to
16+
easily position static elements in figure coordinates.

lib/matplotlib/figure.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1038,6 +1038,42 @@ def fixlist(args):
10381038
key = fixlist(args), fixitems(kwargs.items())
10391039
return key
10401040

1041+
def add_artist(self, artist, clip=False):
1042+
"""
1043+
Add any :class:`~matplotlib.artist.Artist` to the figure.
1044+
1045+
Usually artists are added to axes objects using
1046+
:meth:`matplotlib.axes.Axes.add_artist`, but use this method in the
1047+
rare cases that adding directly to the figure is necessary.
1048+
1049+
Parameters
1050+
----------
1051+
artist : `~matplotlib.artist.Artist`
1052+
The artist to add to the figure. If the added artist has no
1053+
transform set to it previously, its transform will be set to
1054+
``figure.transFigure``.
1055+
clip : bool, optional, default ``False``
1056+
An optional parameter ``clip`` determines whether the added artist
1057+
should be clipped by the figure patch. Default is *False*,
1058+
i.e. no clipping.
1059+
1060+
Returns
1061+
-------
1062+
artist : The added `~matplotlib.artist.Artist`
1063+
"""
1064+
artist.set_figure(self)
1065+
self.artists.append(artist)
1066+
artist._remove_method = self.artists.remove
1067+
1068+
if not artist.is_transform_set():
1069+
artist.set_transform(self.transFigure)
1070+
1071+
if clip:
1072+
artist.set_clip_path(self.patch)
1073+
1074+
self.stale = True
1075+
return artist
1076+
10411077
def add_axes(self, *args, **kwargs):
10421078
"""
10431079
Add an axes to the figure.

lib/matplotlib/tests/test_figure.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import sys
22
import warnings
3+
import io
34

45
from matplotlib import rcParams
56
from matplotlib.testing.decorators import image_comparison
@@ -373,6 +374,34 @@ def test_figure_repr():
373374
assert repr(fig) == "<Figure size 100x200 with 0 Axes>"
374375

375376

377+
def test_add_artist():
378+
fig, ax = plt.subplots(dpi=100)
379+
l1 = plt.Line2D([.2, .7], [.7, .7])
380+
l2 = plt.Line2D([.2, .7], [.8, .8])
381+
r1 = plt.Circle((20, 20), 100, transform=None)
382+
r2 = plt.Circle((.7, .5), .05)
383+
r3 = plt.Circle((4.5, .8), .55, transform=fig.dpi_scale_trans,
384+
facecolor='crimson')
385+
for a in [l1, l2, r1, r2, r3]:
386+
fig.add_artist(a)
387+
l2.remove()
388+
buf1 = io.BytesIO()
389+
fig.savefig(buf1)
390+
391+
fig2, ax2 = plt.subplots(dpi=100)
392+
l1 = plt.Line2D([.2, .7], [.7, .7], transform=fig2.transFigure)
393+
r1 = plt.Circle((20, 20), 100, transform=None, clip_on=False, zorder=20)
394+
r2 = plt.Circle((.7, .5), .05, transform=fig2.transFigure)
395+
r3 = plt.Circle((4.5, .8), .55, transform=fig.dpi_scale_trans,
396+
facecolor='crimson', clip_on=False, zorder=20)
397+
for a in [l1, r1, r2, r3]:
398+
ax2.add_artist(a)
399+
buf2 = io.BytesIO()
400+
fig2.savefig(buf2)
401+
402+
assert buf1.getvalue() == buf2.getvalue()
403+
404+
376405
@pytest.mark.skipif(sys.version_info < (3, 6), reason="requires Python 3.6+")
377406
@pytest.mark.parametrize("fmt", ["png", "pdf", "ps", "eps", "svg"])
378407
def test_fspath(fmt, tmpdir):

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy