def repel_text_from_points(x, y, texts, renderer=None, ax=None,<EOL>expand=(<NUM_LIT>, <NUM_LIT>), move=False):
assert len(x) == len(y)<EOL>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>move_x = np.zeros((len(bboxes), len(x)))<EOL>move_y = np.zeros((len(bboxes), len(x)))<EOL>for i, bbox in enumerate(bboxes):<EOL><INDENT>xy_in = get_points_inside_bbox(x, y, bbox)<EOL>for j in xy_in:<EOL><INDENT>xp, yp = x[j], y[j]<EOL>dx, dy = overlap_bbox_and_point(bbox, xp, yp)<EOL>move_x[i, j] = dx<EOL>move_y[i, j] = dy<EOL><DEDENT><DEDENT>delta_x = move_x.sum(axis=<NUM_LIT:1>)<EOL>delta_y = move_y.sum(axis=<NUM_LIT:1>)<EOL>q = np.sum(np.abs(move_x)), np.sum(np.abs(move_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 all points specified by x and y while expanding their
(texts'!) bounding boxes by expandby  (x, y), e.g. (1.2, 1.2)
would multiply both 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.