@@ -350,35 +350,43 @@ def __init__(self, *args, number=None, main=False, **kwargs):
350350 # Ensure isDefault_minloc enabled at start, needed for dual axes
351351 self .xaxis .isDefault_minloc = self .yaxis .isDefault_minloc = True
352352
353- # Properties
354353 self ._auto_format = None # manipulated by wrapper functions
354+
355355 self ._abc_loc = None
356356 self ._abc_text = None
357357 self ._abc_border_kwargs = {} # abs border properties
358+
358359 self ._title_loc = None # location of main title
359360 self ._title_pad = rc ['axes.titlepad' ] # format() can overwrite
360361 self ._title_pad_active = None
361362 self ._title_border_kwargs = {} # title border properties
363+
362364 self ._above_top_panels = True # TODO: add rc prop?
363365 self ._bottom_panels = []
364366 self ._top_panels = []
365367 self ._left_panels = []
366368 self ._right_panels = []
369+
367370 self ._tightbbox = None # bounding boxes are saved
371+
368372 self ._panel_hidden = False # True when "filled" with cbar/legend
369373 self ._panel_parent = None
370374 self ._panel_share = False
371375 self ._panel_sharex_group = False
372376 self ._panel_sharey_group = False
373377 self ._panel_side = None
378+
374379 self ._inset_parent = None
375380 self ._inset_zoom = False
376381 self ._inset_zoom_data = None
382+
377383 self ._alty_child = None
378384 self ._altx_child = None
379385 self ._alty_parent = None
380386 self ._altx_parent = None
387+
381388 self .number = number # for abc numbering
389+
382390 if main :
383391 self .figure ._axes_main .append (self )
384392
@@ -681,6 +689,15 @@ def inset_locator(ax, renderer):
681689 return bb
682690 return inset_locator
683691
692+ def _plot_redirect (self , name , * args , ** kwargs ):
693+ """
694+ Redirect to the associated basemap method if possible.
695+ """
696+ if getattr (self , 'name' , '' ) == 'basemap' :
697+ return getattr (self .projection , name )(* args , ax = self , ** kwargs )
698+ else :
699+ return getattr (maxes .Axes , name )(self , * args , ** kwargs )
700+
684701 def _range_gridspec (self , x ):
685702 """
686703 Return the column or row gridspec range for the axes.
@@ -1338,7 +1355,7 @@ def barbs(self, *args, **kwargs):
13381355 """
13391356 args = plot ._parse_2d (* args )
13401357 kwargs , kwargs_colorbar = plot ._parse_cmap (** kwargs )
1341- mappable = super (). barbs ( * args , ** kwargs )
1358+ mappable = self . _plot_redirect ( 'barbs' , * args , ** kwargs )
13421359 plot ._auto_colorbar (mappable , ** kwargs_colorbar )
13431360 return mappable
13441361
@@ -1701,7 +1718,7 @@ def contour(self, *args, **kwargs):
17011718 """
17021719 args = plot ._parse_2d (* args )
17031720 kwargs , kwargs_colorbar = plot ._parse_cmap (** kwargs )
1704- mappable = super (). contour ( * args , ** kwargs )
1721+ mappable = self . _plot_redirect ( 'contour' , * args , ** kwargs )
17051722 plot ._auto_colorbar (mappable , ** kwargs_colorbar )
17061723 return mappable
17071724
@@ -1720,10 +1737,15 @@ def contourf(self, *args, **kwargs):
17201737 """
17211738 args = plot ._parse_2d (* args )
17221739 kwargs , kwargs_colorbar = plot ._parse_cmap (** kwargs )
1723- mappable = super (). contourf ( * args , ** kwargs )
1740+ mappable = self . _plot_redirect ( 'contourf' , * args , ** kwargs )
17241741 plot ._auto_colorbar (mappable , ** kwargs_colorbar )
17251742 return mappable
17261743
1744+ def draw (self , renderer = None , * args , ** kwargs ):
1745+ # Perform extra post-processing steps
1746+ self ._reassign_title ()
1747+ super ().draw (renderer , * args , ** kwargs )
1748+
17271749 # fill_between = _fill_between_wrapper(_standardize_1d(_cycle_changer(
17281750 def _fill_between_apply (
17291751 self , xy , * args ,
@@ -1834,101 +1856,6 @@ def fill_betweenx(self, *args, **kwargs):
18341856 """
18351857 return self ._fill_between_apply ('yx' , * args , ** kwargs )
18361858
1837- @plot ._concatenate_docstrings
1838- @docstring .add_snippets
1839- def legend (self , * args , loc = None , width = None , space = None , ** kwargs ):
1840- """
1841- Add an *inset* legend or *outer* legend along the edge of the axes.
1842-
1843- Parameters
1844- ----------
1845- %(plot.legend_args)s
1846- loc : int or str, optional
1847- The legend location. The following location keys are valid:
1848-
1849- .. _legend_table:
1850-
1851- ================== =======================================
1852- Location Valid keys
1853- ================== =======================================
1854- outer left ``'left'``, ``'l'``
1855- outer right ``'right'``, ``'r'``
1856- outer bottom ``'bottom'``, ``'b'``
1857- outer top ``'top'``, ``'t'``
1858- "best" inset ``'best'``, ``'inset'``, ``'i'``, ``0``
1859- upper right inset ``'upper right'``, ``'ur'``, ``1``
1860- upper left inset ``'upper left'``, ``'ul'``, ``2``
1861- lower left inset ``'lower left'``, ``'ll'``, ``3``
1862- lower right inset ``'lower right'``, ``'lr'``, ``4``
1863- center left inset ``'center left'``, ``'cl'``, ``5``
1864- center right inset ``'center right'``, ``'cr'``, ``6``
1865- lower center inset ``'lower center'``, ``'lc'``, ``7``
1866- upper center inset ``'upper center'``, ``'uc'``, ``8``
1867- center inset ``'center'``, ``'c'``, ``9``
1868- "filled" ``'fill'``
1869- ================== =======================================
1870-
1871- width : float or str, optional
1872- For outer legends only. The space allocated for the legend box.
1873- This does nothing if :rcraw:`tight` is ``True``. Units are
1874- interpreted by `~proplot.utils.units`.
1875- space : float or str, optional
1876- For outer legends only. The space between the axes and the legend
1877- box. Units are interpreted by `~proplot.utils.units`.
1878- When :rcraw:`tight` is ``True``, this is adjusted automatically.
1879- Otherwise, the default is :rc:`subplots.panelpad`.
1880- %(plot.legend_kwargs)s
1881-
1882- Other parameters
1883- ----------------
1884- **kwargs
1885- Passed to `~matplotlib.axes.Axes.legend`.
1886- """
1887- if loc != 'fill' :
1888- loc = self ._loc_translate (loc , 'legend' )
1889- if isinstance (loc , np .ndarray ):
1890- loc = loc .tolist ()
1891-
1892- # Generate panel
1893- if loc in ('left' , 'right' , 'top' , 'bottom' ):
1894- ax = self .panel_axes (loc , width = width , space = space , filled = True )
1895- return ax .legend (* args , loc = 'fill' , ** kwargs )
1896-
1897- # Fill
1898- if loc == 'fill' :
1899- # Hide content
1900- self ._hide_panel ()
1901-
1902- # Try to make handles and stuff flush against the axes edge
1903- kwargs .setdefault ('borderaxespad' , 0 )
1904- frameon = _not_none (
1905- kwargs .get ('frame' , None ), kwargs .get ('frameon' , None ),
1906- rc ['legend.frameon' ]
1907- )
1908- if not frameon :
1909- kwargs .setdefault ('borderpad' , 0 )
1910-
1911- # Apply legend location
1912- side = self ._panel_side
1913- if side == 'bottom' :
1914- loc = 'upper center'
1915- elif side == 'right' :
1916- loc = 'center left'
1917- elif side == 'left' :
1918- loc = 'center right'
1919- elif side == 'top' :
1920- loc = 'lower center'
1921- else :
1922- raise ValueError (f'Invalid panel side { side !r} .' )
1923-
1924- # Draw legend
1925- return plot ._add_legend (self , * args , loc = loc , ** kwargs )
1926-
1927- def draw (self , renderer = None , * args , ** kwargs ):
1928- # Perform extra post-processing steps
1929- self ._reassign_title ()
1930- super ().draw (renderer , * args , ** kwargs )
1931-
19321859 def get_size_inches (self ):
19331860 # Return the width and height of the axes in inches.
19341861 width , height = self .figure .get_size_inches ()
@@ -2000,7 +1927,7 @@ def hexbin(self, *args, **kwargs):
20001927 """
20011928 args = plot ._parse_1d (* args )
20021929 kwargs , kwargs_colorbar = plot ._parse_cmap (** kwargs )
2003- mappable = super (). hexbin ( * args , ** kwargs )
1930+ mappable = self . _plot_redirect ( 'hexbin' , * args , ** kwargs )
20041931 plot ._auto_colorbar (mappable , ** kwargs_colorbar )
20051932 return mappable
20061933
@@ -2140,7 +2067,7 @@ def imshow(self, *args, **kwargs):
21402067 %(plot.cmap_args)s
21412068 """
21422069 kwargs , kwargs_colorbar = plot ._parse_cmap (** kwargs )
2143- mappable = super (). imshow ( * args , ** kwargs )
2070+ mappable = self . _plot_redirect ( 'imshow' , * args , ** kwargs )
21442071 plot ._auto_colorbar (mappable , ** kwargs_colorbar )
21452072 return mappable
21462073
@@ -2292,6 +2219,96 @@ def indicate_inset_zoom(
22922219 self ._inset_zoom_data = (rectpatch , connects )
22932220 return rectpatch , connects
22942221
2222+ @plot ._concatenate_docstrings
2223+ @docstring .add_snippets
2224+ def legend (self , * args , loc = None , width = None , space = None , ** kwargs ):
2225+ """
2226+ Add an *inset* legend or *outer* legend along the edge of the axes.
2227+
2228+ Parameters
2229+ ----------
2230+ %(plot.legend_args)s
2231+ loc : int or str, optional
2232+ The legend location. The following location keys are valid:
2233+
2234+ .. _legend_table:
2235+
2236+ ================== =======================================
2237+ Location Valid keys
2238+ ================== =======================================
2239+ outer left ``'left'``, ``'l'``
2240+ outer right ``'right'``, ``'r'``
2241+ outer bottom ``'bottom'``, ``'b'``
2242+ outer top ``'top'``, ``'t'``
2243+ "best" inset ``'best'``, ``'inset'``, ``'i'``, ``0``
2244+ upper right inset ``'upper right'``, ``'ur'``, ``1``
2245+ upper left inset ``'upper left'``, ``'ul'``, ``2``
2246+ lower left inset ``'lower left'``, ``'ll'``, ``3``
2247+ lower right inset ``'lower right'``, ``'lr'``, ``4``
2248+ center left inset ``'center left'``, ``'cl'``, ``5``
2249+ center right inset ``'center right'``, ``'cr'``, ``6``
2250+ lower center inset ``'lower center'``, ``'lc'``, ``7``
2251+ upper center inset ``'upper center'``, ``'uc'``, ``8``
2252+ center inset ``'center'``, ``'c'``, ``9``
2253+ "filled" ``'fill'``
2254+ ================== =======================================
2255+
2256+ width : float or str, optional
2257+ For outer legends only. The space allocated for the legend box.
2258+ This does nothing if :rcraw:`tight` is ``True``. Units are
2259+ interpreted by `~proplot.utils.units`.
2260+ space : float or str, optional
2261+ For outer legends only. The space between the axes and the legend
2262+ box. Units are interpreted by `~proplot.utils.units`.
2263+ When :rcraw:`tight` is ``True``, this is adjusted automatically.
2264+ Otherwise, the default is :rc:`subplots.panelpad`.
2265+ %(plot.legend_kwargs)s
2266+
2267+ Other parameters
2268+ ----------------
2269+ **kwargs
2270+ Passed to `~matplotlib.axes.Axes.legend`.
2271+ """
2272+ if loc != 'fill' :
2273+ loc = self ._loc_translate (loc , 'legend' )
2274+ if isinstance (loc , np .ndarray ):
2275+ loc = loc .tolist ()
2276+
2277+ # Generate panel
2278+ if loc in ('left' , 'right' , 'top' , 'bottom' ):
2279+ ax = self .panel_axes (loc , width = width , space = space , filled = True )
2280+ return ax .legend (* args , loc = 'fill' , ** kwargs )
2281+
2282+ # Fill
2283+ if loc == 'fill' :
2284+ # Hide content
2285+ self ._hide_panel ()
2286+
2287+ # Try to make handles and stuff flush against the axes edge
2288+ kwargs .setdefault ('borderaxespad' , 0 )
2289+ frameon = _not_none (
2290+ kwargs .get ('frame' , None ), kwargs .get ('frameon' , None ),
2291+ rc ['legend.frameon' ]
2292+ )
2293+ if not frameon :
2294+ kwargs .setdefault ('borderpad' , 0 )
2295+
2296+ # Apply legend location
2297+ side = self ._panel_side
2298+ if side == 'bottom' :
2299+ loc = 'upper center'
2300+ elif side == 'right' :
2301+ loc = 'center left'
2302+ elif side == 'left' :
2303+ loc = 'center right'
2304+ elif side == 'top' :
2305+ loc = 'lower center'
2306+ else :
2307+ raise ValueError (f'Invalid panel side { side !r} .' )
2308+
2309+ # Draw legend
2310+ return plot ._add_legend (self , * args , loc = loc , ** kwargs )
2311+
22952312 @plot ._concatenate_docstrings
22962313 @docstring .add_snippets
22972314 def matshow (self , * args , ** kwargs ):
@@ -2466,7 +2483,7 @@ def pcolor(self, *args, **kwargs):
24662483 """
24672484 args = plot ._parse_2d (* args )
24682485 kwargs , kwargs_colorbar = plot ._parse_cmap (** kwargs )
2469- mappable = super (). pcolor ( * args , ** kwargs )
2486+ mappable = self . _plot_redirect ( 'pcolor' , * args , ** kwargs )
24702487 plot ._auto_colorbar (mappable , ** kwargs_colorbar )
24712488 return mappable
24722489
@@ -2504,7 +2521,7 @@ def pcolormesh(self, *args, **kwargs):
25042521 """
25052522 args = plot ._parse_2d (* args )
25062523 kwargs , kwargs_colorbar = plot ._parse_cmap (** kwargs )
2507- mappable = super (). pcolormesh ( * args , ** kwargs )
2524+ mappable = self . _plot_redirect ( 'pcolormesh' , * args , ** kwargs )
25082525 plot ._auto_colorbar (mappable , ** kwargs_colorbar )
25092526 return mappable
25102527
@@ -2565,7 +2582,7 @@ def plot(self, *args, cmap=None, values=None, **kwargs):
25652582 kwargs , kwargs_legend_colorbar = plot ._parse_cycle (** kwargs )
25662583
25672584 # Draw lines
2568- objs = super (). plot ( x , y , values = values , ** kwargs )
2585+ objs = self . _plot_redirect ( 'plot' , x , y , values = values , ** kwargs )
25692586
25702587 # Add sticky edges? No because there is no way to check whether "dependent
25712588 # variable" is x or y axis like with area/areax and bar/barh. Better to always
@@ -2598,7 +2615,7 @@ def quiver(self, *args, **kwargs):
25982615 """
25992616 args = plot ._parse_2d (* args )
26002617 kwargs , kwargs_colorbar = plot ._parse_cmap (** kwargs )
2601- mappable = super (). quiver ( * args , ** kwargs )
2618+ mappable = self . _plot_redirect ( 'quiver' , * args , ** kwargs )
26022619 plot ._auto_colorbar (mappable , ** kwargs_colorbar )
26032620 return mappable
26042621
@@ -2725,8 +2742,8 @@ def scatter(
27252742 )
27262743
27272744 # Draw scatterplot
2728- objs = super (). scatter (
2729- * args , c = c , s = s , cmap = cmap , norm = norm ,
2745+ objs = self . _plot_redirect (
2746+ 'scatter' , * args , c = c , s = s , cmap = cmap , norm = norm ,
27302747 linewidths = lw , edgecolors = ec , ** kwargs
27312748 )
27322749 if ticks is not None :
@@ -2813,7 +2830,7 @@ def streamplot(self, *args, **kwargs):
28132830 """
28142831 args = plot ._parse_2d (* args )
28152832 kwargs , kwargs_colorbar = plot ._parse_cmap (** kwargs )
2816- mappable = super (). streamplot ( * args , ** kwargs )
2833+ mappable = self . _plot_redirect ( 'streamplot' , * args , ** kwargs )
28172834 plot ._auto_colorbar (mappable , ** kwargs_colorbar )
28182835 return mappable
28192836
0 commit comments