@@ -583,39 +583,67 @@ def get_subplotspec(self):
583
583
return None
584
584
585
585
586
- class HBoxDivider (SubplotDivider ):
586
+ # Helper for HBoxDivider/VBoxDivider.
587
+ def _determine_karray (equivalent_sizes , appended_sizes ,
588
+ max_equivalent_size , total_appended_size ):
589
+ n = len (equivalent_sizes )
590
+ eq_rs , eq_as = np .asarray (equivalent_sizes ).T
591
+ ap_rs , ap_as = np .asarray (appended_sizes ).T
592
+ A = np .zeros ((n + 1 , n + 1 ))
593
+ B = np .zeros (n + 1 )
594
+ np .fill_diagonal (A [:n , :n ], eq_rs )
595
+ A [:n , - 1 ] = - 1
596
+ A [- 1 , :- 1 ] = ap_rs
597
+ B [:n ] = - eq_as
598
+ B [- 1 ] = total_appended_size - sum (ap_as )
599
+ # A @ K = B: This solves for {k_0, ..., k_{N-1}, H} so that
600
+ # eq_r_i * k_i + eq_a_i = H for all i: all axes have the same height
601
+ # sum(ap_r_i * k_i + ap_a_i) = total_summed_width: fixed total width
602
+ # (foo_r_i * k_i + foo_a_i will end up being the size of foo.)
603
+ karray_H = np .linalg .solve (A , B )
604
+ karray = karray_H [:- 1 ]
605
+ H = karray_H [- 1 ]
606
+ if H > max_equivalent_size : # Additionally, upper-bound the height.
607
+ karray = (max_equivalent_size - eq_as ) / eq_rs
608
+ return karray
609
+
610
+
611
+ # Helper for HBoxDivider/VBoxDivider.
612
+ def _calc_offsets (appended_sizes , karray ):
613
+ offsets = [0. ]
614
+ for (r , a ), k in zip (appended_sizes , karray ):
615
+ offsets .append (offsets [- 1 ] + r * k + a )
616
+ return offsets
617
+
618
+
619
+ # Helper for HBoxDivider/VBoxDivider.
620
+ def _locate (
621
+ x , y , w , h , equivalent_sizes , appended_sizes , fig_w , fig_h , anchor ):
622
+ karray = _determine_karray (
623
+ equivalent_sizes , appended_sizes ,
624
+ max_equivalent_size = fig_h * h , total_appended_size = fig_w * w )
625
+ ox = _calc_offsets (appended_sizes , karray )
626
+
627
+ ww = (ox [- 1 ] - ox [0 ]) / fig_w
628
+ h0_r , h0_a = equivalent_sizes [0 ]
629
+ hh = (karray [0 ]* h0_r + h0_a ) / fig_h
630
+ pb = mtransforms .Bbox .from_bounds (x , y , w , h )
631
+ pb1 = mtransforms .Bbox .from_bounds (x , y , ww , hh )
632
+ pb1_anchored = pb1 .anchored (anchor , pb )
633
+ x0 , y0 = pb1_anchored .x0 , pb1_anchored .y0
634
+
635
+ return x0 , y0 , ox , hh
587
636
588
- @staticmethod
589
- def _determine_karray (equivalent_sizes , appended_sizes ,
590
- max_equivalent_size ,
591
- total_appended_size ):
592
- n = len (equivalent_sizes )
593
- eq_rs , eq_as = np .asarray (equivalent_sizes ).T
594
- ap_rs , ap_as = np .asarray (appended_sizes ).T
595
- A = np .zeros ((n + 1 , n + 1 ))
596
- B = np .zeros (n + 1 )
597
- np .fill_diagonal (A [:n , :n ], eq_rs )
598
- A [:n , - 1 ] = - 1
599
- A [- 1 , :- 1 ] = ap_rs
600
- B [:n ] = - eq_as
601
- B [- 1 ] = total_appended_size - sum (ap_as )
602
- # A @ K = B: This solves for {k_0, ..., k_{N-1}, H} so that
603
- # eq_r_i * k_i + eq_a_i = H for all i: all axes have the same height
604
- # sum(ap_r_i * k_i + ap_a_i) = total_appended_size: fixed total width
605
- # (foo_r_i * k_i + foo_a_i will end up being the size of foo.)
606
- karray_H = np .linalg .solve (A , B )
607
- karray = karray_H [:- 1 ]
608
- H = karray_H [- 1 ]
609
- if H > max_equivalent_size : # Additionally, upper-bound the height.
610
- karray = (max_equivalent_size - eq_as ) / eq_rs
611
- return karray
612
637
613
- @staticmethod
614
- def _calc_offsets (appended_sizes , karray ):
615
- offsets = [0. ]
616
- for (r , a ), k in zip (appended_sizes , karray ):
617
- offsets .append (offsets [- 1 ] + r * k + a )
618
- return offsets
638
+ class HBoxDivider (SubplotDivider ):
639
+ """
640
+ A `SubplotDivider` for laying out axes horizontally, while ensuring that
641
+ they have equal heights.
642
+
643
+ Examples
644
+ --------
645
+ .. plot:: gallery/axes_grid1/demo_axes_hbox_divider.py
646
+ """
619
647
620
648
def new_locator (self , nx , nx1 = None ):
621
649
"""
@@ -631,52 +659,26 @@ def new_locator(self, nx, nx1=None):
631
659
"""
632
660
return AxesLocator (self , nx , 0 , nx1 , None )
633
661
634
- def _locate (self , x , y , w , h ,
635
- y_equivalent_sizes , x_appended_sizes ,
636
- figW , figH ):
637
- equivalent_sizes = y_equivalent_sizes
638
- appended_sizes = x_appended_sizes
639
-
640
- max_equivalent_size = figH * h
641
- total_appended_size = figW * w
642
- karray = self ._determine_karray (equivalent_sizes , appended_sizes ,
643
- max_equivalent_size ,
644
- total_appended_size )
645
-
646
- ox = self ._calc_offsets (appended_sizes , karray )
647
-
648
- ww = (ox [- 1 ] - ox [0 ]) / figW
649
- ref_h = equivalent_sizes [0 ]
650
- hh = (karray [0 ]* ref_h [0 ] + ref_h [1 ]) / figH
651
- pb = mtransforms .Bbox .from_bounds (x , y , w , h )
652
- pb1 = mtransforms .Bbox .from_bounds (x , y , ww , hh )
653
- pb1_anchored = pb1 .anchored (self .get_anchor (), pb )
654
- x0 , y0 = pb1_anchored .x0 , pb1_anchored .y0
655
-
656
- return x0 , y0 , ox , hh
657
-
658
662
def locate (self , nx , ny , nx1 = None , ny1 = None , axes = None , renderer = None ):
659
663
# docstring inherited
660
664
figW , figH = self ._fig .get_size_inches ()
661
665
x , y , w , h = self .get_position_runtime (axes , renderer )
662
-
663
666
y_equivalent_sizes = self .get_vertical_sizes (renderer )
664
667
x_appended_sizes = self .get_horizontal_sizes (renderer )
665
- x0 , y0 , ox , hh = self . _locate (x , y , w , h ,
666
- y_equivalent_sizes , x_appended_sizes ,
667
- figW , figH )
668
+ x0 , y0 , ox , hh = _locate (x , y , w , h ,
669
+ y_equivalent_sizes , x_appended_sizes ,
670
+ figW , figH , self . get_anchor () )
668
671
if nx1 is None :
669
672
nx1 = nx + 1
670
-
671
673
x1 , w1 = x0 + ox [nx ] / figW , (ox [nx1 ] - ox [nx ]) / figW
672
674
y1 , h1 = y0 , hh
673
-
674
675
return mtransforms .Bbox .from_bounds (x1 , y1 , w1 , h1 )
675
676
676
677
677
- class VBoxDivider (HBoxDivider ):
678
+ class VBoxDivider (SubplotDivider ):
678
679
"""
679
- The Divider class whose rectangle area is specified as a subplot geometry.
680
+ A `SubplotDivider` for laying out axes vertically, while ensuring that they
681
+ have equal widths.
680
682
"""
681
683
682
684
def new_locator (self , ny , ny1 = None ):
@@ -697,18 +699,15 @@ def locate(self, nx, ny, nx1=None, ny1=None, axes=None, renderer=None):
697
699
# docstring inherited
698
700
figW , figH = self ._fig .get_size_inches ()
699
701
x , y , w , h = self .get_position_runtime (axes , renderer )
700
-
701
702
x_equivalent_sizes = self .get_horizontal_sizes (renderer )
702
703
y_appended_sizes = self .get_vertical_sizes (renderer )
703
- y0 , x0 , oy , ww = self . _locate (y , x , h , w ,
704
- x_equivalent_sizes , y_appended_sizes ,
705
- figH , figW )
704
+ y0 , x0 , oy , ww = _locate (y , x , h , w ,
705
+ x_equivalent_sizes , y_appended_sizes ,
706
+ figH , figW , self . get_anchor () )
706
707
if ny1 is None :
707
708
ny1 = ny + 1
708
-
709
709
x1 , w1 = x0 , ww
710
710
y1 , h1 = y0 + oy [ny ] / figH , (oy [ny1 ] - oy [ny ]) / figH
711
-
712
711
return mtransforms .Bbox .from_bounds (x1 , y1 , w1 , h1 )
713
712
714
713
0 commit comments