How can I convert from scatter size to data coordinates in matplotlib?

I would like to programmatically check if two characters of the scattered plane overlap in matplotlib. Therefore, given the pair of coordinates (x, y) and the size (which, as I understand it, is the area of ​​the circle, in points), I would like to build

plt.scatter(x, y, s=s) 

and then the points_overlap function, which takes these parameters and returns True if the points overlap, and False otherwise.

 def points_overlap(x, y, s): if ... return True else: return False 

I know that there are transformation matrices to take me between the various matplotlib coordinate systems , but I cannot figure out the right steps to write this function.

+7
python matplotlib
source share
1 answer

It takes some testing, but it might work? All must be in the display area.

 def overlap(x, y, sx, sy): return np.linalg.norm(x - y) < np.linalg.norm(sx + sy) 

Test:

 In [227]: X = np.array([[1, 1], [2, 1], [2.5, 1]]) In [228]: s = np.array([20, 10000, 10000]) In [229]: fig, ax = plt.subplots() In [230]: ax.scatter(X[:, 0], X[:, 1], s=s) Out[230]: <matplotlib.collections.PathCollection at 0x10c32f28> In [231]: plt.draw() 

Check each pair:

 Xt = ax.transData.transform(X) st = np.sqrt(s) pairs = product(Xt, Xt) sizes = product(st, st) for i, ((x, y), (sx, sy)) in enumerate(zip(pairs, sizes)): h = i % 3 j = i // 3 if h != j and overlap(x, y, sx, sy): print((i, h, j)) 

enter image description here

There are many opportunities for improvement. It is probably easier to convert all of your data and pass it to the points_overlap function instead of doing the conversion inside. That would be much better.

+2
source share

All Articles