def repel_text_from_bboxes(add_bboxes, texts, renderer=None, ax=None,<EOL>expand=(<NUM_LIT>, <NUM_LIT>), only_use_max_min=False,<EOL>move=False):
if ax is None:<EOL><INDENT>ax = plt.gca()<EOL><DEDENT>if renderer is None:<EOL><INDENT>r = get_renderer(ax.get_figure())<EOL><DEDENT>else:<EOL><INDENT>r = renderer<EOL><DEDENT>bboxes = get_bboxes(texts, r, expand, ax=ax)<EOL>overlaps_x = np.zeros((len(bboxes), len(add_bboxes)))<EOL>overlaps_y = np.zeros_like(overlaps_x)<EOL>overlap_directions_x = np.zeros_like(overlaps_x)<EOL>overlap_directions_y = np.zeros_like(overlaps_y)<EOL>for i, bbox1 in enumerate(bboxes):<EOL><INDENT>for j, bbox2 in enumerate(add_bboxes):<EOL><INDENT>try:<EOL><INDENT>x, y = bbox1.intersection(bbox1, bbox2).size<EOL>direction = np.sign(bbox1.extents - bbox2.extents)[:<NUM_LIT:2>]<EOL>overlaps_x[i, j] = x<EOL>overlaps_y[i, j] = y<EOL>overlap_directions_x[i, j] = direction[<NUM_LIT:0>]<EOL>overlap_directions_y[i, j] = direction[<NUM_LIT:1>]<EOL><DEDENT>except AttributeError:<EOL><INDENT>pass<EOL><DEDENT><DEDENT><DEDENT>move_x = overlaps_x*overlap_directions_x<EOL>move_y = overlaps_y*overlap_directions_y<EOL>delta_x = move_x.sum(axis=<NUM_LIT:1>)<EOL>delta_y = move_y.sum(axis=<NUM_LIT:1>)<EOL>q = np.sum(overlaps_x), np.sum(overlaps_y)<EOL>if move:<EOL><INDENT>move_texts(texts, delta_x, delta_y, bboxes, ax=ax)<EOL><DEDENT>return delta_x, delta_y, q<EOL>
Repel texts from other objects' bboxes while expanding their (texts')
bounding boxes by expand (x, y), e.g. (1.2, 1.2) would multiply width and
height by 1.2.
Requires a renderer to get the actual sizes of the text, and to that end
either one needs to be directly provided, or the axes have to be specified,
and the renderer is then got from the axes object.