def repel_text(texts, renderer=None, ax=None, expand=(<NUM_LIT>, <NUM_LIT>),<EOL>only_use_max_min=False, 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>xmins = [bbox.xmin for bbox in bboxes]<EOL>xmaxs = [bbox.xmax for bbox in bboxes]<EOL>ymaxs = [bbox.ymax for bbox in bboxes]<EOL>ymins = [bbox.ymin for bbox in bboxes]<EOL>overlaps_x = np.zeros((len(bboxes), len(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>overlaps = get_points_inside_bbox(xmins*<NUM_LIT:2>+xmaxs*<NUM_LIT:2>, (ymins+ymaxs)*<NUM_LIT:2>,<EOL>bbox1) % len(bboxes)<EOL>overlaps = np.unique(overlaps)<EOL>for j in overlaps:<EOL><INDENT>bbox2 = bboxes[j]<EOL>x, y = bbox1.intersection(bbox1, bbox2).size<EOL>overlaps_x[i, j] = x<EOL>overlaps_y[i, j] = y<EOL>direction = np.sign(bbox1.extents - bbox2.extents)[:<NUM_LIT:2>]<EOL>overlap_directions_x[i, j] = direction[<NUM_LIT:0>]<EOL>overlap_directions_y[i, j] = direction[<NUM_LIT:1>]<EOL><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 each other while expanding their 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.