(x, y, w, h, summed_widths, equal_heights, fig_w, fig_h, anchor)
| 481 | # The variable names are written for a horizontal layout, but the calculations |
| 482 | # work identically for vertical layouts. |
| 483 | def _locate(x, y, w, h, summed_widths, equal_heights, fig_w, fig_h, anchor): |
| 484 | |
| 485 | total_width = fig_w * w |
| 486 | max_height = fig_h * h |
| 487 | |
| 488 | # Determine the k factors. |
| 489 | n = len(equal_heights) |
| 490 | eq_rels, eq_abss = equal_heights.T |
| 491 | sm_rels, sm_abss = summed_widths.T |
| 492 | A = np.diag([*eq_rels, 0]) |
| 493 | A[:n, -1] = -1 |
| 494 | A[-1, :-1] = sm_rels |
| 495 | B = [*(-eq_abss), total_width - sm_abss.sum()] |
| 496 | # A @ K = B: This finds factors {k_0, ..., k_{N-1}, H} so that |
| 497 | # eq_rel_i * k_i + eq_abs_i = H for all i: all axes have the same height |
| 498 | # sum(sm_rel_i * k_i + sm_abs_i) = total_width: fixed total width |
| 499 | # (foo_rel_i * k_i + foo_abs_i will end up being the size of foo.) |
| 500 | *karray, height = np.linalg.solve(A, B) |
| 501 | if height > max_height: # Additionally, upper-bound the height. |
| 502 | karray = (max_height - eq_abss) / eq_rels |
| 503 | |
| 504 | # Compute the offsets corresponding to these factors. |
| 505 | ox = np.cumsum([0, *(sm_rels * karray + sm_abss)]) |
| 506 | ww = (ox[-1] - ox[0]) / fig_w |
| 507 | h0_rel, h0_abs = equal_heights[0] |
| 508 | hh = (karray[0]*h0_rel + h0_abs) / fig_h |
| 509 | pb = mtransforms.Bbox.from_bounds(x, y, w, h) |
| 510 | pb1 = mtransforms.Bbox.from_bounds(x, y, ww, hh) |
| 511 | x0, y0 = pb1.anchored(anchor, pb).p0 |
| 512 | |
| 513 | return x0, y0, ox, hh |
| 514 | |
| 515 | |
| 516 | class HBoxDivider(SubplotDivider): |
no test coverage detected
searching dependent graphs…