Arrow pointing to marker edge regardless of marker size

This goes in the same direction as this question .

I want to point an arrow from one scatter point to another so that the arrow is near the edge of the marker. As in the following example:

import matplotlib.pyplot as plt
import matplotlib as mpl

fig, ax = plt.subplots()
ax.scatter([0,1],[0,1], s=300)
arrow = mpl.patches.FancyArrowPatch(posA=(0,0), posB=(1,1), arrowstyle='-|>', mutation_scale=20, shrinkA=7, shrinkB=7)
plt.show()

      

enter image description here

Here I have selected the values shrinkA

and shrinkB

manually so that the arrow is very close to the edge of the target scatter point. However, I would change these values ​​if I changed the size of the markers.

My question is, knowing the size of the markers (kwarg s

in ax.scatter), how to select shrinkA

and shrinkB

so that the arrow lies close to the edge of the marker?

I know what s

is measured in p ^ 2 where p is the typographic point. Thus, the radius of the marker is sqrt(s / pi)

. If shrinkA

u shrinkB

are measured at the same typographic points, we could just do shrinkB=radius

where radius

is the radius of the marker.

With s == 300 this makes sense, since the radius is close to 9.8.

+1


source to share


1 answer


Arguments shrinkA

/ shrinkB

FancyArrowPatch

expect their argument in dot units. Points are also line width units or markers. For a scatter plot, the size argument s

is the square of the markersis.

Therefore, taking into account the size

scattering of graphics s=size

, shrink

it is calculated by taking squareroot and divide by 2 (because you want to compress the arrow radius, not the diameter).

shrink = math.sqrt(size)/2.

      



Example:

import matplotlib.pyplot as plt
import matplotlib as mpl
import math

fig, ax = plt.subplots()
size = 1000
radius = math.sqrt(size)/2.
points = ax.scatter([0,1], [0,1], s=size)
arrow = mpl.patches.FancyArrowPatch(posA=(0,0), posB=(1,1), 
                                    arrowstyle='-|>', mutation_scale=20, 
                                    shrinkA=radius, shrinkB=radius)
ax.add_patch(arrow)

plt.show()

      

enter image description here

+1


source







All Articles