@@ -55,32 +55,10 @@ def __init__(self, fig, pos, horizontal, vertical,
5555 self ._locator = None
5656
5757 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 ()])
5959
6060 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 ()])
8462
8563 def set_position (self , pos ):
8664 """
@@ -171,6 +149,19 @@ def get_position_runtime(self, ax, renderer):
171149 else :
172150 return self ._locator (ax , renderer ).bounds
173151
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+
174165 def locate (self , nx , ny , nx1 = None , ny1 = None , axes = None , renderer = None ):
175166 """
176167 Parameters
@@ -542,48 +533,33 @@ def get_subplotspec(self):
542533
543534# Helper for HBoxDivider/VBoxDivider.
544535# 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.
547543 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 ])
553547 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 )
564555 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
583557
558+ # Compute the offsets corresponding to these factors.
559+ ox = np .cumsum ([0 , * (sm_rels * karray + sm_abss )])
584560 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
587563 pb = mtransforms .Bbox .from_bounds (x , y , w , h )
588564 pb1 = mtransforms .Bbox .from_bounds (x , y , ww , hh )
589565 x0 , y0 = pb1 .anchored (anchor , pb ).p0
0 commit comments