@@ -105,12 +105,12 @@ def __init__(self, *args, number=None, main=False, **kwargs):
105
105
self ._left_panels = []
106
106
self ._right_panels = []
107
107
self ._tightbbox = None # bounding boxes are saved
108
+ self ._panel_hidden = False # True when "filled" with cbar/legend
108
109
self ._panel_parent = None
109
- self ._panel_side = None
110
110
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
114
114
self ._inset_parent = None
115
115
self ._inset_zoom = False
116
116
self ._inset_zoom_data = None
@@ -174,9 +174,63 @@ def __init__(self, *args, number=None, main=False, **kwargs):
174
174
175
175
# Automatic axis sharing and formatting
176
176
# TODO: Instead of format() call specific setters
177
- self ._share_setup ()
177
+ self ._auto_share_setup ()
178
178
self .format (rc_mode = 1 ) # mode == 1 applies the rcShortParams
179
179
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
+
180
234
def _draw_auto_legends_colorbars (self ):
181
235
"""
182
236
Generate automatic legends and colorbars. Wrapper funcs
@@ -259,10 +313,21 @@ def _hide_panel(self):
259
313
self .patch .set_alpha (0 )
260
314
self ._panel_hidden = True
261
315
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
+
262
328
def _loc_translate (self , loc , mode = None , allow_manual = True ):
263
329
"""
264
- Return the location string `loc` translated into a standardized
265
- form.
330
+ Return the location string `loc` translated into a standardized form.
266
331
"""
267
332
if mode == 'legend' :
268
333
valid = tuple (LOC_TRANSLATE .values ())
@@ -357,7 +422,7 @@ def _range_tightbbox(self, x):
357
422
else :
358
423
return bbox .ymin , bbox .ymax
359
424
360
- def _reassign_suplabel (self , side ):
425
+ def _reassign_subplot_label (self , side ):
361
426
"""
362
427
Re-assign the column and row labels to the relevant panel if
363
428
present. This is called by `~proplot.figure.Figure._align_suplabel`.
@@ -422,82 +487,21 @@ def _sharex_setup(self, sharex):
422
487
Configure x-axis sharing for panels. Main axis sharing is done in
423
488
`~CartesianAxes._sharex_setup`.
424
489
"""
425
- self ._share_short_axis (sharex , 'left' )
490
+ self ._share_short_axis (sharex , 'left' ) # x axis of left panels
426
491
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
428
493
self ._share_long_axis (sharex , 'top' )
429
494
430
495
def _sharey_setup (self , sharey ):
431
496
"""
432
497
Configure y-axis sharing for panels. Main axis sharing is done in
433
498
`~CartesianAxes._sharey_setup`.
434
499
"""
435
- self ._share_short_axis (sharey , 'bottom' )
500
+ self ._share_short_axis (sharey , 'bottom' ) # y axis of bottom panels
436
501
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
438
503
self ._share_long_axis (sharey , 'right' )
439
504
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
-
501
505
def _share_short_axis (self , share , side ):
502
506
"""
503
507
Share the "short" axes of panels belonging to this subplot
@@ -528,38 +532,6 @@ def _share_long_axis(self, share, side):
528
532
for pax in paxs :
529
533
getattr (pax , '_share' + axis + '_setup' )(share )
530
534
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
-
563
535
def _update_title_position (self , renderer ):
564
536
"""
565
537
Update the position of proplot inset titles and builtin matplotlib
@@ -775,7 +747,7 @@ def format(
775
747
'fontfamily' : 'font.family'
776
748
}, context = True )
777
749
if suptitle or kw :
778
- fig ._update_figtitle (suptitle , ** kw )
750
+ fig ._update_super_title (suptitle , ** kw )
779
751
780
752
# Labels
781
753
rlabels = _not_none (rightlabels = rightlabels , rlabels = rlabels )
@@ -797,7 +769,7 @@ def format(
797
769
'fontfamily' : 'font.family'
798
770
}, context = True )
799
771
if labels or kw :
800
- fig ._update_labels (self , side , labels , ** kw )
772
+ fig ._update_subplot_labels (self , side , labels , ** kw )
801
773
802
774
# Helper function
803
775
def sanitize_kw (kw , loc ):
@@ -1320,7 +1292,7 @@ def heatmap(self, *args, aspect=None, **kwargs):
1320
1292
"""
1321
1293
obj = self .pcolormesh (* args , ** kwargs )
1322
1294
aspect = _not_none (aspect , rc ['image.aspect' ])
1323
- xlocator , ylocator = None , None
1295
+ xlocator = ylocator = None
1324
1296
if hasattr (obj , '_coordinates' ):
1325
1297
coords = obj ._coordinates
1326
1298
coords = (coords [1 :, ...] + coords [:- 1 , ...]) / 2
@@ -1475,7 +1447,7 @@ def indicate_inset_zoom(
1475
1447
line .set_visible (visible )
1476
1448
line_prev .set_visible (False )
1477
1449
self ._inset_zoom_data = (rectpatch , connects )
1478
- return ( rectpatch , connects )
1450
+ return rectpatch , connects
1479
1451
1480
1452
def panel_axes (self , side , ** kwargs ):
1481
1453
"""
@@ -1542,9 +1514,8 @@ def parametric(
1542
1514
number of additional color levels between the line joints
1543
1515
and the halfway points between line joints.
1544
1516
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`.
1548
1519
1549
1520
Other parameters
1550
1521
----------------
@@ -1587,17 +1558,20 @@ def parametric(
1587
1558
coords , cmap = cmap , norm = norm ,
1588
1559
linestyles = '-' , capstyle = 'butt' , joinstyle = 'miter' ,
1589
1560
)
1590
- hs .set_array (np .array (values ))
1561
+ values = np .asarray (values )
1562
+ hs .set_array (values )
1591
1563
hs .update ({
1592
1564
key : value for key , value in kwargs .items ()
1593
1565
if key not in ('color' ,)
1594
1566
})
1595
1567
1596
1568
# 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.
1597
1571
self .add_collection (hs )
1598
1572
self .autoscale_view (scalex = scalex , scaley = scaley )
1599
1573
hs .values = values
1600
- hs .levels = levels # needed for other functions some
1574
+ hs .levels = levels # needed for other functions
1601
1575
return hs
1602
1576
1603
1577
def violins (self , * args , ** kwargs ):
0 commit comments