1
votes

Given a matplotlib 2.0.0 scatter plot with few points, I want to annotate some of the points without overlapping other points. For the annotation, I use adjustText which takes an optional list of matplotlib objects (with the .get_window_extent() method) to avoid. But I could not yet find out how to get those objects for the points in the scatter plot.

How can I get a list of (point) objects having .get_window_extent() from the scatter plot?

Consider for example:

import matplotlib.pyplot as plt
from adjustText import adjust_text
x,y = [1,2,3,4,5],[2,4,6,8,10]
scatter = plt.scatter(x,y)
annotations = []
for x_i, y_i in zip(x[:-3],y[:-3]):
    annotations.append(plt.text(x_i,y_i, 'foobar'))
adjust_text(annotations, add_objects=scatter)

Using add_objects=

  • scatter throws a TypeError: 'PathCollection' object is not iterable
  • scatter.get_paths() throws a AttributeError: 'Path' object has no attribute 'get_window_extent'
1
Looks like scatter.get_children() is the solution!Kibour
Actually, scatter.get_children() returns an empty list.Kibour

1 Answers

3
votes

I think you simply missed the additional arguments in adjust_text. You may supply the x and y coordinates of the points directly to the function:

adjust_text(annotations,x=x,y=y)

Full example:

import matplotlib.pyplot as plt
from adjustText import adjust_text
plt.rcParams["figure.figsize"] = 3,2
x,y = [1,2,3,4,5],[2,4,2,8,10]
scatter = plt.scatter(x,y)
annotations = []
for x_i, y_i in zip(x,y):
    annotations.append(plt.text(x_i,y_i, 'foobar {},{}'.format(x_i,y_i)))
adjust_text(annotations,x=x,y=y)

plt.show()

enter image description here