@@ -105,12 +105,12 @@ def __init__(self, *args, number=None, main=False, **kwargs):
105105 self ._left_panels = []
106106 self ._right_panels = []
107107 self ._tightbbox = None # bounding boxes are saved
108+ self ._panel_hidden = False # True when "filled" with cbar/legend
108109 self ._panel_parent = None
109- self ._panel_side = None
110110 self ._panel_share = False
111- self ._panel_hidden = False # True when "filled" with cbar/legend
112- self ._sharex_override = False
113- self ._sharey_override = False
111+ self ._panel_sharex_group = False
112+ self ._panel_sharey_group = False
113+ self ._panel_side = None
114114 self ._inset_parent = None
115115 self ._inset_zoom = False
116116 self ._inset_zoom_data = None
@@ -174,9 +174,63 @@ def __init__(self, *args, number=None, main=False, **kwargs):
174174
175175 # Automatic axis sharing and formatting
176176 # TODO: Instead of format() call specific setters
177- self ._share_setup ()
177+ self ._auto_share_setup ()
178178 self .format (rc_mode = 1 ) # mode == 1 applies the rcShortParams
179179
180+ def _auto_share_setup (self ):
181+ """
182+ Automatically configure axis sharing based on the horizontal and
183+ vertical extent of subplots in the figure gridspec.
184+ """
185+ # Panel axes sharing, between main subplot and its panels
186+ # NOTE: _panel_share means "include this panel in the axis sharing group"
187+ # while _panel_sharex_group indicates the group itself and may include main axes
188+ def shared (paxs ):
189+ return [pax for pax in paxs if not pax ._panel_hidden and pax ._panel_share ]
190+
191+ # Internal axis sharing, share stacks of panels and main axes with each other
192+ # NOTE: *This* block is why, even though share[xy] are figure-wide
193+ # settings, we still need the axes-specific _share[xy]_override attr
194+ if not self ._panel_side : # this is a main axes
195+ # Top and bottom
196+ bottom = self
197+ paxs = shared (self ._bottom_panels )
198+ if paxs :
199+ bottom = paxs [- 1 ]
200+ bottom ._panel_sharex_group = False
201+ for iax in (self , * paxs [:- 1 ]):
202+ iax ._panel_sharex_group = True
203+ iax ._sharex_setup (bottom ) # parent is bottom-most
204+ paxs = shared (self ._top_panels )
205+ for iax in paxs :
206+ iax ._panel_sharex_group = True
207+ iax ._sharex_setup (bottom )
208+ # Left and right
209+ # NOTE: Order of panel lists is always inside-to-outside
210+ left = self
211+ paxs = shared (self ._left_panels )
212+ if paxs :
213+ left = paxs [- 1 ]
214+ left ._panel_sharey_group = False
215+ for iax in (self , * paxs [:- 1 ]):
216+ iax ._panel_sharey_group = True
217+ iax ._sharey_setup (left ) # parent is left-most
218+ paxs = shared (self ._right_panels )
219+ for iax in paxs :
220+ iax ._panel_sharey_group = True
221+ iax ._sharey_setup (left )
222+
223+ # External axes sharing, sometimes overrides panel axes sharing
224+ # NOTE: This can get very repetitive, but probably minimal impact?
225+ # Share x axes
226+ parent , * children = self ._get_extent_axes ('x' )
227+ for child in children :
228+ child ._sharex_setup (parent )
229+ # Share y axes
230+ parent , * children = self ._get_extent_axes ('y' )
231+ for child in children :
232+ child ._sharey_setup (parent )
233+
180234 def _draw_auto_legends_colorbars (self ):
181235 """
182236 Generate automatic legends and colorbars. Wrapper funcs
@@ -259,10 +313,21 @@ def _hide_panel(self):
259313 self .patch .set_alpha (0 )
260314 self ._panel_hidden = True
261315
316+ def _is_panel (self ):
317+ """
318+ Return whether the current axes is a panel.
319+ """
320+ return bool (self ._panel_parent )
321+
322+ def _is_panel_parent_or_child (self , other ):
323+ """
324+ Return whether the axes are related.
325+ """
326+ return self ._panel_parent is other or other ._panel_parent is self
327+
262328 def _loc_translate (self , loc , mode = None , allow_manual = True ):
263329 """
264- Return the location string `loc` translated into a standardized
265- form.
330+ Return the location string `loc` translated into a standardized form.
266331 """
267332 if mode == 'legend' :
268333 valid = tuple (LOC_TRANSLATE .values ())
@@ -357,7 +422,7 @@ def _range_tightbbox(self, x):
357422 else :
358423 return bbox .ymin , bbox .ymax
359424
360- def _reassign_suplabel (self , side ):
425+ def _reassign_subplot_label (self , side ):
361426 """
362427 Re-assign the column and row labels to the relevant panel if
363428 present. This is called by `~proplot.figure.Figure._align_suplabel`.
@@ -422,82 +487,21 @@ def _sharex_setup(self, sharex):
422487 Configure x-axis sharing for panels. Main axis sharing is done in
423488 `~CartesianAxes._sharex_setup`.
424489 """
425- self ._share_short_axis (sharex , 'left' )
490+ self ._share_short_axis (sharex , 'left' ) # x axis of left panels
426491 self ._share_short_axis (sharex , 'right' )
427- self ._share_long_axis (sharex , 'bottom' )
492+ self ._share_long_axis (sharex , 'bottom' ) # x axis of bottom panels
428493 self ._share_long_axis (sharex , 'top' )
429494
430495 def _sharey_setup (self , sharey ):
431496 """
432497 Configure y-axis sharing for panels. Main axis sharing is done in
433498 `~CartesianAxes._sharey_setup`.
434499 """
435- self ._share_short_axis (sharey , 'bottom' )
500+ self ._share_short_axis (sharey , 'bottom' ) # y axis of bottom panels
436501 self ._share_short_axis (sharey , 'top' )
437- self ._share_long_axis (sharey , 'left' )
502+ self ._share_long_axis (sharey , 'left' ) # y axis of left panels
438503 self ._share_long_axis (sharey , 'right' )
439504
440- def _share_setup (self ):
441- """
442- Automatically configure axis sharing based on the horizontal and
443- vertical extent of subplots in the figure gridspec.
444- """
445- # Panel axes sharing, between main subplot and its panels
446- # NOTE: While _panel_share just means "include this panel" in the
447- # axis sharing between the main subplot and panel children,
448- # _sharex_override and _sharey_override say "override the sharing level
449- # for these axes, because they belong to a panel group", and may
450- # include the main subplot itself.
451- def shared (paxs ):
452- return [
453- pax for pax in paxs
454- if not pax ._panel_hidden and pax ._panel_share
455- ]
456-
457- # Internal axis sharing; share stacks of panels and the main
458- # axes with each other.
459- # NOTE: *This* block is why, even though share[xy] are figure-wide
460- # settings, we still need the axes-specific _share[xy]_override attr
461- if not self ._panel_side : # this is a main axes
462- # Top and bottom
463- bottom = self
464- paxs = shared (self ._bottom_panels )
465- if paxs :
466- bottom = paxs [- 1 ]
467- bottom ._sharex_override = False
468- for iax in (self , * paxs [:- 1 ]):
469- iax ._sharex_override = True
470- iax ._sharex_setup (bottom ) # parent is bottom-most
471- paxs = shared (self ._top_panels )
472- for iax in paxs :
473- iax ._sharex_override = True
474- iax ._sharex_setup (bottom )
475- # Left and right
476- # NOTE: Order of panel lists is always inside-to-outside
477- left = self
478- paxs = shared (self ._left_panels )
479- if paxs :
480- left = paxs [- 1 ]
481- left ._sharey_override = False
482- for iax in (self , * paxs [:- 1 ]):
483- iax ._sharey_override = True
484- iax ._sharey_setup (left ) # parent is left-most
485- paxs = shared (self ._right_panels )
486- for iax in paxs :
487- iax ._sharey_override = True
488- iax ._sharey_setup (left )
489-
490- # Main axes, sometimes overrides panel axes sharing
491- # TODO: This can get very repetitive, but probably minimal impact?
492- # Share x axes
493- parent , * children = self ._get_extent_axes ('x' )
494- for child in children :
495- child ._sharex_setup (parent )
496- # Share y axes
497- parent , * children = self ._get_extent_axes ('y' )
498- for child in children :
499- child ._sharey_setup (parent )
500-
501505 def _share_short_axis (self , share , side ):
502506 """
503507 Share the "short" axes of panels belonging to this subplot
@@ -528,38 +532,6 @@ def _share_long_axis(self, share, side):
528532 for pax in paxs :
529533 getattr (pax , '_share' + axis + '_setup' )(share )
530534
531- def _update_axis_labels (self , x = 'x' , ** kwargs ):
532- """
533- Apply axis labels to the relevant shared axis. If spanning
534- labels are toggled this keeps the labels synced for all subplots in
535- the same row or column. Label positions will be adjusted at draw-time
536- with figure._align_axislabels.
537- """
538- # TODO: Major issues with this algorithm, especially when twin axes
539- # are present.
540- # TODO: Share axis locators and formatters just like matplotlib shares
541- # axis limits and proplot shares axis labels.
542- if x not in 'xy' :
543- return
544-
545- # Update label on this axes
546- axis = getattr (self , x + 'axis' )
547- axis .label .update (kwargs )
548- kwargs .pop ('color' , None )
549- if getattr (self .figure , '_share' + x ) == 0 :
550- return
551-
552- # Get "shared axes" siblings
553- ax , * _ = self ._get_extent_axes (x , panels = True )
554- axs = [ax ]
555- if getattr (ax .figure , '_span' + x ):
556- side = axis .get_label_position ()
557- if side in ('left' , 'bottom' ):
558- axs = ax ._get_side_axes (side , panels = True )
559- for ax in axs :
560- axis = getattr (ax , x + 'axis' )
561- axis .label .update (kwargs ) # apply to main axes
562-
563535 def _update_title_position (self , renderer ):
564536 """
565537 Update the position of proplot inset titles and builtin matplotlib
@@ -775,7 +747,7 @@ def format(
775747 'fontfamily' : 'font.family'
776748 }, context = True )
777749 if suptitle or kw :
778- fig ._update_figtitle (suptitle , ** kw )
750+ fig ._update_super_title (suptitle , ** kw )
779751
780752 # Labels
781753 rlabels = _not_none (rightlabels = rightlabels , rlabels = rlabels )
@@ -797,7 +769,7 @@ def format(
797769 'fontfamily' : 'font.family'
798770 }, context = True )
799771 if labels or kw :
800- fig ._update_labels (self , side , labels , ** kw )
772+ fig ._update_subplot_labels (self , side , labels , ** kw )
801773
802774 # Helper function
803775 def sanitize_kw (kw , loc ):
@@ -1320,7 +1292,7 @@ def heatmap(self, *args, aspect=None, **kwargs):
13201292 """
13211293 obj = self .pcolormesh (* args , ** kwargs )
13221294 aspect = _not_none (aspect , rc ['image.aspect' ])
1323- xlocator , ylocator = None , None
1295+ xlocator = ylocator = None
13241296 if hasattr (obj , '_coordinates' ):
13251297 coords = obj ._coordinates
13261298 coords = (coords [1 :, ...] + coords [:- 1 , ...]) / 2
@@ -1475,7 +1447,7 @@ def indicate_inset_zoom(
14751447 line .set_visible (visible )
14761448 line_prev .set_visible (False )
14771449 self ._inset_zoom_data = (rectpatch , connects )
1478- return ( rectpatch , connects )
1450+ return rectpatch , connects
14791451
14801452 def panel_axes (self , side , ** kwargs ):
14811453 """
@@ -1542,9 +1514,8 @@ def parametric(
15421514 number of additional color levels between the line joints
15431515 and the halfway points between line joints.
15441516 scalex, scaley : bool, optional
1545- These parameters determine if the view limits are adapted to
1546- the data limits. The values are passed on to
1547- `~matplotlib.axes.Axes.autoscale_view`.
1517+ Whether the view limits are adapted to the data limits. The values are
1518+ passed on to `~matplotlib.axes.Axes.autoscale_view`.
15481519
15491520 Other parameters
15501521 ----------------
@@ -1587,17 +1558,20 @@ def parametric(
15871558 coords , cmap = cmap , norm = norm ,
15881559 linestyles = '-' , capstyle = 'butt' , joinstyle = 'miter' ,
15891560 )
1590- hs .set_array (np .array (values ))
1561+ values = np .asarray (values )
1562+ hs .set_array (values )
15911563 hs .update ({
15921564 key : value for key , value in kwargs .items ()
15931565 if key not in ('color' ,)
15941566 })
15951567
15961568 # Add collection with some custom attributes
1569+ # NOTE: Modern API uses self._request_autoscale_view but this is
1570+ # backwards compatible to earliest matplotlib versions.
15971571 self .add_collection (hs )
15981572 self .autoscale_view (scalex = scalex , scaley = scaley )
15991573 hs .values = values
1600- hs .levels = levels # needed for other functions some
1574+ hs .levels = levels # needed for other functions
16011575 return hs
16021576
16031577 def violins (self , * args , ** kwargs ):
0 commit comments