Skip to content

[Bug]: Possible bug on arrows in annotation #21733

Closed

Description

@jason-sachs

Bug summary

Arrow behavior in axes.annotate is inconsistent depending on the direction of the xy coordinate.

Arrow line begins at center of text in cases of horizontal/vertical lines, but begins at lower left of text in cases of diagonal lines.

Code for reproduction

import matplotlib.pyplot as plt

fig = plt.figure()
ax = fig.add_subplot(1,1,1)
ax.set_xlim(0,1)
ax.set_ylim(0,1)
ax.set_aspect('equal')
ax.grid(True)
for target in ((0.2,0.2),(0.2,0.4),(0.2,0.6),(0.4,0.2),(0.6,0.2)):
    ax.annotate('Blah! Blah blah blah.',xy=target, xytext=(0.6,0.6),
                 bbox=dict(boxstyle='round', facecolor='none'),
                 ha='center',va='center',
                 arrowprops=dict(facecolor='black',width=0.8,headwidth=5,connectionstyle="arc3,rad=0"))

Actual outcome:

matplotlib2

Expected outcome

Arrow starting point should be consistent, or at least adjustable; relpos is not available as a FancyArrowPatch key, so if I add it, I get AttributeError: 'FancyArrowPatch' object has no property 'relpos'

Additional information

No response

Operating system

Windows

Matplotlib Version

import matplotlib; print(matplotlib.version)

Matplotlib Backend

module://matplotlib_inline.backend_inline

Python version

3.7.4

Jupyter version

6.1.4

Installation

conda

Activity

  1. timhoffm commented on Nov 24, 2021

    @timhoffm
    Member

    The question is: On which angles do we want to change the anchor point?

    Currently the rules seem to be:

    • exactly horizontal lines attach to the side centers.
    • everything else goes to the nearest x-position from horizontal center and edges.

    grafik

    import matplotlib.pyplot as plt
    
    fig, ax = plt.subplots()
    ax.set(xlim =(0, 2), ylim=(0, 2))
    ax.set_aspect('equal')
    ax.grid(True)
    
    phi = np.linspace(0, 2*np.pi, 145)
    x = np.cos(phi) + 1
    y = np.sin(phi) + 1
    
    for xi, yi in zip(x, y):
        ax.annotate('Blah! Blah blah blah.',xy=(xi, yi), xytext=(1, 1),
                     bbox=dict(boxstyle='round', facecolor='none'),
                     ha='center',va='center',
                     arrowprops=dict(facecolor='black',width=0.8,headwidth=5,connectionstyle="arc3,rad=0"))
    
  2. anntzer commented on Nov 24, 2021

    @anntzer
    Contributor

    The relevant logic is at

    # pick the corner of the text bbox closest to annotated point.
    xpos = [(bbox.x0, 0), ((bbox.x0 + bbox.x1) / 2, 0.5), (bbox.x1, 1)]
    ypos = [(bbox.y0, 0), ((bbox.y0 + bbox.y1) / 2, 0.5), (bbox.y1, 1)]
    x, relposx = min(xpos, key=lambda v: abs(v[0] - x1))
    y, relposy = min(ypos, key=lambda v: abs(v[0] - y1))
    self._arrow_relpos = (relposx, relposy)
    I think.

  3. jason-sachs commented on Nov 24, 2021

    @jason-sachs
    Author

    I don't mind the existing implementation if it's documented -- it was a bit of a surprise to me.

    self._arrow_relpos = (relposx, relposy) 
    

    ...or allow the user to override this somehow.

  4. jason-sachs commented on Nov 24, 2021

    @jason-sachs
    Author

    Eventually, I gave up trying to do what I wanted (just have arrows emanating from the center of the block by trying to use relpos as I mentioned in #21732 ) and took an approach in StackOverflow and just created separate annotations for the arrows and for the text.

  5. timhoffm commented on Nov 24, 2021

    @timhoffm
    Member

    what I wanted (just have arrows emanating from the center of the block by trying to use relpos as I mentioned in #21732 )

    @jason-sachs that's possible if you specify an arrowstyle, e.g. arrowprops=dict(arrowstyle='-|>', facecolor='black'). You can also use relpos here if you want.
    There are two different draw routines with different behavior and I hope #21743 makes this more clear.

    grafik

  6. jason-sachs commented on Nov 29, 2021

    @jason-sachs
    Author

    Yeah, I tried that, but using arrowstyle doesn't let me get the type of arrowhead I want.

  7. timhoffm commented on Nov 29, 2021

    @timhoffm
    Member

    Which type of head would you want?

  8. modified the milestones: v3.5-doc, v3.5.1 on Nov 30, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions