@@ -55,32 +55,10 @@ def __init__(self, fig, pos, horizontal, vertical,
55
55
self ._locator = None
56
56
57
57
def get_horizontal_sizes (self , renderer ):
58
- return [s .get_size (renderer ) for s in self .get_horizontal ()]
58
+ return np . array ( [s .get_size (renderer ) for s in self .get_horizontal ()])
59
59
60
60
def get_vertical_sizes (self , renderer ):
61
- return [s .get_size (renderer ) for s in self .get_vertical ()]
62
-
63
- @staticmethod
64
- def _calc_k (l , total_size ):
65
-
66
- rs_sum , as_sum = 0. , 0.
67
-
68
- for _rs , _as in l :
69
- rs_sum += _rs
70
- as_sum += _as
71
-
72
- if rs_sum != 0. :
73
- k = (total_size - as_sum ) / rs_sum
74
- return k
75
- else :
76
- return 0.
77
-
78
- @staticmethod
79
- def _calc_offsets (l , k ):
80
- offsets = [0. ]
81
- for _rs , _as in l :
82
- offsets .append (offsets [- 1 ] + _rs * k + _as )
83
- return offsets
61
+ return np .array ([s .get_size (renderer ) for s in self .get_vertical ()])
84
62
85
63
def set_position (self , pos ):
86
64
"""
@@ -171,6 +149,19 @@ def get_position_runtime(self, ax, renderer):
171
149
else :
172
150
return self ._locator (ax , renderer ).bounds
173
151
152
+ @staticmethod
153
+ def _calc_k (sizes , total ):
154
+ # sizes is a (n, 2) array of (rel_size, abs_size); this method finds
155
+ # the k factor such that sum(rel_size * k + abs_size) == total.
156
+ rel_sum , abs_sum = sizes .sum (0 )
157
+ return (total - abs_sum ) / rel_sum if rel_sum else 0
158
+
159
+ @staticmethod
160
+ def _calc_offsets (sizes , k ):
161
+ # Apply k factors to (n, 2) sizes array of (rel_size, abs_size); return
162
+ # the resulting cumulative offset positions.
163
+ return np .cumsum ([0 , * (sizes @ [k , 1 ])])
164
+
174
165
def locate (self , nx , ny , nx1 = None , ny1 = None , axes = None , renderer = None ):
175
166
"""
176
167
Parameters
@@ -542,48 +533,33 @@ def get_subplotspec(self):
542
533
543
534
# Helper for HBoxDivider/VBoxDivider.
544
535
# The variable names are written for a horizontal layout, but the calculations
545
- # work identically for vertical layouts (and likewise for the helpers below).
546
- def _determine_karray (summed_widths , equal_heights , total_width , max_height ):
536
+ # work identically for vertical layouts.
537
+ def _locate (x , y , w , h , summed_widths , equal_heights , fig_w , fig_h , anchor ):
538
+
539
+ total_width = fig_w * w
540
+ max_height = fig_h * h
541
+
542
+ # Determine the k factors.
547
543
n = len (equal_heights )
548
- eq_rs , eq_as = np .asarray (equal_heights ).T
549
- sm_rs , sm_as = np .asarray (summed_widths ).T
550
- A = np .zeros ((n + 1 , n + 1 ))
551
- B = np .zeros (n + 1 )
552
- np .fill_diagonal (A [:n , :n ], eq_rs )
544
+ eq_rels , eq_abss = equal_heights .T
545
+ sm_rels , sm_abss = summed_widths .T
546
+ A = np .diag ([* eq_rels , 0 ])
553
547
A [:n , - 1 ] = - 1
554
- A [- 1 , :- 1 ] = sm_rs
555
- B [:n ] = - eq_as
556
- B [- 1 ] = total_width - sum (sm_as )
557
- # A @ K = B: This solves for {k_0, ..., k_{N-1}, H} so that
558
- # eq_r_i * k_i + eq_a_i = H for all i: all axes have the same height
559
- # sum(sm_r_i * k_i + sm_a_i) = total_summed_width: fixed total width
560
- # (foo_r_i * k_i + foo_a_i will end up being the size of foo.)
561
- karray_and_height = np .linalg .solve (A , B )
562
- karray = karray_and_height [:- 1 ]
563
- height = karray_and_height [- 1 ]
548
+ A [- 1 , :- 1 ] = sm_rels
549
+ B = [* (- eq_abss ), total_width - sm_abss .sum ()]
550
+ # A @ K = B: This finds factors {k_0, ..., k_{N-1}, H} so that
551
+ # eq_rel_i * k_i + eq_abs_i = H for all i: all axes have the same height
552
+ # sum(sm_rel_i * k_i + sm_abs_i) = total_width: fixed total width
553
+ # (foo_rel_i * k_i + foo_abs_i will end up being the size of foo.)
554
+ * karray , height = np .linalg .solve (A , B )
564
555
if height > max_height : # Additionally, upper-bound the height.
565
- karray = (max_height - eq_as ) / eq_rs
566
- return karray
567
-
568
-
569
- # Helper for HBoxDivider/VBoxDivider (see above re: variable naming).
570
- def _calc_offsets (summed_sizes , karray ):
571
- offsets = [0. ]
572
- for (r , a ), k in zip (summed_sizes , karray ):
573
- offsets .append (offsets [- 1 ] + r * k + a )
574
- return offsets
575
-
576
-
577
- # Helper for HBoxDivider/VBoxDivider (see above re: variable naming).
578
- def _locate (x , y , w , h , summed_widths , equal_heights , fig_w , fig_h , anchor ):
579
- karray = _determine_karray (
580
- summed_widths , equal_heights ,
581
- total_width = fig_w * w , max_height = fig_h * h )
582
- ox = _calc_offsets (summed_widths , karray )
556
+ karray = (max_height - eq_abss ) / eq_rels
583
557
558
+ # Compute the offsets corresponding to these factors.
559
+ ox = np .cumsum ([0 , * (sm_rels * karray + sm_abss )])
584
560
ww = (ox [- 1 ] - ox [0 ]) / fig_w
585
- h0_r , h0_a = equal_heights [0 ]
586
- hh = (karray [0 ]* h0_r + h0_a ) / fig_h
561
+ h0_rel , h0_abs = equal_heights [0 ]
562
+ hh = (karray [0 ]* h0_rel + h0_abs ) / fig_h
587
563
pb = mtransforms .Bbox .from_bounds (x , y , w , h )
588
564
pb1 = mtransforms .Bbox .from_bounds (x , y , ww , hh )
589
565
x0 , y0 = pb1 .anchored (anchor , pb ).p0
0 commit comments