How to set xytext as starting point for annotate arrow using matplotlib?
Asked Answered
S

1

0

I would like to gain more control over the starting point of the annotation arrow in Matplotlib. It seems like the arrow starts at the center of the bbox of the annotation text. However, in many cases I would like to make the xytext coordinates the starting point of the arrow. I visualise my problem below for datapoint (0, 0) and xytext (1, 1) in data coordinates:

import matplotlib.pyplot as plt

fig = plt.figure()
ax = fig.add_subplot()
    
ax.plot(0, 0, linestyle='none', marker='o', markersize=4, c='k')
    
ax.annotate('annotation', [0, 0], xytext=[1, 1],
            ha='left', va='center',
            bbox=dict(pad=0, fc='none', ec='k'),
            arrowprops=dict(arrowstyle='-'))
    
ax.plot(1, 1, linestyle='none', marker='o', markersize=4, c='red')
    
ax.annotate('desired\nanchorpoint', [1, 1], xytext=[0, 1],
            ha='center', va='center',
            arrowprops=dict(arrowstyle='->', shrinkB=5))
    
ax.set_xlim([-1, 2])
ax.set_ylim([-1, 2])

enter image description here

It is possible to make one annotation without text and another with text only and no arrow, like proposed in this answer.

I would prefer a solution that uses just one instance of annotate. Is it possible to set xytext as starting point for the arrow of annotate?

Schultz answered 17/2, 2023 at 12:37 Comment(0)
L
1

You can do it using the arrow property relpos. From the matplotlib tutorials:

By default, the starting point is set to the center of the text extent. This can be adjusted with relpos key value. The values are normalized to the extent of the text. For example, (0, 0) means lower-left corner and (1, 1) means top-right.

Adapting your example:

ax.plot(0,0,linestyle='none',marker='o',markersize=4,c='k')
ax.annotate(
    'annotation',
    [0, 0],xytext=[1, 1],
    ha='left', va='center',
    bbox=dict(pad=0, fc='none', ec='k'),
    arrowprops=dict(
        arrowstyle='-',
        relpos=(0., 0.5),
        shrinkA=0,
    )
)

Graph with example of custom relpos

Ligule answered 20/2, 2023 at 16:56 Comment(2)
Great, this is not so clear from the documentation and I am not doing all tutorials. Did you know or did this actually show up on an internet search? (for me it did not)Schultz
Search it and explored the tutorials (first result).Ligule

© 2022 - 2025 — McMap. All rights reserved.