1717import numpy as np
1818
1919from matplotlib import rcParams
20- from matplotlib import backends , docstring
20+ from matplotlib import backends , docstring , projections
2121from matplotlib import __version__ as _mpl_version
2222from matplotlib import get_backend
2323
@@ -1021,6 +1021,42 @@ def delaxes(self, ax):
10211021 func (self )
10221022 self .stale = True
10231023
1024+ def add_artist (self , artist , clip = False ):
1025+ """
1026+ Add any :class:`~matplotlib.artist.Artist` to the figure.
1027+
1028+ Usually artists are added to axes objects using
1029+ :meth:`matplotlib.axes.Axes.add_artist`, but use this method in the
1030+ rare cases that adding directly to the figure is necessary.
1031+
1032+ Parameters
1033+ ----------
1034+ artist : `~matplotlib.artist.Artist`
1035+ The artist to add to the figure. If the added artist has no
1036+ transform previously set, its transform will be set to
1037+ ``figure.transFigure``.
1038+ clip : bool, optional, default ``False``
1039+ An optional parameter ``clip`` determines whether the added artist
1040+ should be clipped by the figure patch. Default is *False*,
1041+ i.e. no clipping.
1042+
1043+ Returns
1044+ -------
1045+ artist : The added `~matplotlib.artist.Artist`
1046+ """
1047+ artist .set_figure (self )
1048+ self .artists .append (artist )
1049+ artist ._remove_method = self .artists .remove
1050+
1051+ if not artist .is_transform_set ():
1052+ artist .set_transform (self .transFigure )
1053+
1054+ if clip :
1055+ artist .set_clip_path (self .patch )
1056+
1057+ self .stale = True
1058+ return artist
1059+
10241060 def _make_key (self , * args , ** kwargs ):
10251061 """Make a hashable key out of args and kwargs."""
10261062
@@ -1051,41 +1087,37 @@ def fixlist(args):
10511087 key = fixlist (args ), fixitems (kwargs .items ())
10521088 return key
10531089
1054- def add_artist (self , artist , clip = False ):
1090+ def _process_projection_requirements (
1091+ self , * args , polar = False , projection = None , ** kwargs ):
10551092 """
1056- Add any :class:`~matplotlib.artist.Artist` to the figure.
1093+ Handle the args/kwargs to add_axes/add_subplot/gca, returning::
10571094
1058- Usually artists are added to axes objects using
1059- :meth:`matplotlib.axes.Axes.add_artist`, but use this method in the
1060- rare cases that adding directly to the figure is necessary.
1095+ (axes_proj_class, proj_class_kwargs, proj_stack_key)
10611096
1062- Parameters
1063- ----------
1064- artist : `~matplotlib.artist.Artist`
1065- The artist to add to the figure. If the added artist has no
1066- transform previously set, its transform will be set to
1067- ``figure.transFigure``.
1068- clip : bool, optional, default ``False``
1069- An optional parameter ``clip`` determines whether the added artist
1070- should be clipped by the figure patch. Default is *False*,
1071- i.e. no clipping.
1072-
1073- Returns
1074- -------
1075- artist : The added `~matplotlib.artist.Artist`
1097+ which can be used for new axes initialization/identification.
10761098 """
1077- artist .set_figure (self )
1078- self .artists .append (artist )
1079- artist ._remove_method = self .artists .remove
1080-
1081- if not artist .is_transform_set ():
1082- artist .set_transform (self .transFigure )
1099+ if polar :
1100+ if projection is not None and projection != 'polar' :
1101+ raise ValueError (
1102+ "polar=True, yet projection=%r. "
1103+ "Only one of these arguments should be supplied." %
1104+ projection )
1105+ projection = 'polar'
1106+
1107+ if isinstance (projection , str ) or projection is None :
1108+ projection_class = projections .get_projection_class (projection )
1109+ elif hasattr (projection , '_as_mpl_axes' ):
1110+ projection_class , extra_kwargs = projection ._as_mpl_axes ()
1111+ kwargs .update (** extra_kwargs )
1112+ else :
1113+ raise TypeError ('projection must be a string, None or implement a '
1114+ '_as_mpl_axes method. Got %r' % projection )
10831115
1084- if clip :
1085- artist .set_clip_path (self .patch )
1116+ # Make the key without projection kwargs, this is used as a unique
1117+ # lookup for axes instances
1118+ key = self ._make_key (* args , ** kwargs )
10861119
1087- self .stale = True
1088- return artist
1120+ return projection_class , kwargs , key
10891121
10901122 @docstring .dedent_interpd
10911123 def add_axes (self , * args , ** kwargs ):
@@ -1199,8 +1231,8 @@ def add_axes(self, *args, **kwargs):
11991231 if not np .isfinite (rect ).all ():
12001232 raise ValueError ('all entries in rect must be finite '
12011233 'not {}' .format (rect ))
1202- projection_class , kwargs , key = process_projection_requirements (
1203- self , * args , ** kwargs )
1234+ projection_class , kwargs , key = \
1235+ self . _process_projection_requirements ( * args , ** kwargs )
12041236
12051237 # check that an axes of this type doesn't already exist, if it
12061238 # does, set it as active and return it
@@ -1212,12 +1244,7 @@ def add_axes(self, *args, **kwargs):
12121244 # create the new axes using the axes class given
12131245 a = projection_class (self , rect , ** kwargs )
12141246
1215- self ._axstack .add (key , a )
1216- self .sca (a )
1217- a ._remove_method = self ._remove_ax
1218- self .stale = True
1219- a .stale_callback = _stale_figure_callback
1220- return a
1247+ return self ._add_axes_internal (key , a )
12211248
12221249 @docstring .dedent_interpd
12231250 def add_subplot (self , * args , ** kwargs ):
@@ -1351,8 +1378,8 @@ def add_subplot(self, *args, **kwargs):
13511378 # in the hash)
13521379 key = self ._make_key (* args , ** kwargs )
13531380 else :
1354- projection_class , kwargs , key = process_projection_requirements (
1355- self , * args , ** kwargs )
1381+ projection_class , kwargs , key = \
1382+ self . _process_projection_requirements ( * args , ** kwargs )
13561383
13571384 # try to find the axes with this key in the stack
13581385 ax = self ._axstack .get (key )
@@ -1371,12 +1398,17 @@ def add_subplot(self, *args, **kwargs):
13711398 self ._axstack .remove (ax )
13721399
13731400 a = subplot_class_factory (projection_class )(self , * args , ** kwargs )
1374- self ._axstack .add (key , a )
1375- self .sca (a )
1376- a ._remove_method = self ._remove_ax
1401+
1402+ return self ._add_axes_internal (key , a )
1403+
1404+ def _add_axes_internal (self , key , ax ):
1405+ """Private helper for `add_axes` and `add_subplot`."""
1406+ self ._axstack .add (key , ax )
1407+ self .sca (ax )
1408+ ax ._remove_method = self ._remove_ax
13771409 self .stale = True
1378- a .stale_callback = _stale_figure_callback
1379- return a
1410+ ax .stale_callback = _stale_figure_callback
1411+ return ax
13801412
13811413 def subplots (self , nrows = 1 , ncols = 1 , sharex = False , sharey = False ,
13821414 squeeze = True , subplot_kw = None , gridspec_kw = None ):
@@ -1868,8 +1900,8 @@ def gca(self, **kwargs):
18681900 # if the user has specified particular projection detail
18691901 # then build up a key which can represent this
18701902 else :
1871- projection_class , _ , key = process_projection_requirements (
1872- self , ** kwargs )
1903+ projection_class , _ , key = \
1904+ self . _process_projection_requirements ( ** kwargs )
18731905
18741906 # let the returned axes have any gridspec by removing it from
18751907 # the key
0 commit comments