Skip to content

[Bug]: setting patchA of Annotation.arrow_patch has no effect #28316

Open

Description

@Phlya

Bug summary

I am trying to improve some edge cases for plotting arrows in adjustText. Without going into details, sometimes I have to use ax.annotate to add arrows instead of directly using FancyArrowPatch. However in this case the arrows are not associated with the text objects and strike through them. I thought I could modify the arrow patch of the Annotation object to point to the corresponding Text object. The object appears to be set correctly, however this doesn't fix the clipping of the arrow! With a regular FancyArrowPatch this procedure works just as expected. Interestingly, if I update other properties (color) it works perfectly.

(As an aside, why do the two arrows have a different style in the example below?)

Code for reproduction

import matplotlib.pyplot as plt
from matplotlib import patches
xytext = 0.2, 0.5
f, ax = plt.subplots()
ann = ax.annotate('', xy=(0.5, 0.6), xytext=xytext, arrowprops=dict(arrowstyle="->"))
ann_arrowpatch = ann.arrow_patch
print(ann_arrowpatch.patchA)
text = plt.text(xytext[0], xytext[1], 'Text', ha='center', va='center')
ann_arrowpatch.set_patchA(text)
print(ann_arrowpatch.patchA)

ann_arrowpatch.set_color('b')

arrowpatch = patches.FancyArrowPatch(posA=xytext, posB=(0.5, 0.4), arrowstyle="->", color='r')
ax.add_patch(arrowpatch)
print(arrowpatch.patchA)
arrowpatch.set_patchA(text)
print(arrowpatch.patchA)

Actual outcome

None
Text(0.2, 0.5, 'Text')
None
Text(0.2, 0.5, 'Text')

image

Expected outcome

Expect that the blue arrow is also clipped by the Text

Additional information

No response

Operating system

OS/X

Matplotlib Version

3.8.0

Matplotlib Backend

both inline and ipympl

Python version

3.11.7

Jupyter version

6.4.5

Installation

conda

Activity

  1. Phlya commented on May 30, 2024

    @Phlya
    ContributorAuthor

    Relevant issue in adjustText Phlya/adjustText#175

  2. timhoffm commented on May 31, 2024

    @timhoffm
    Member

    This is indeed surprising. It's even better to see when using ]-> arrows. Also arrow scales are significantly different in the two approaches. There's something very fishy here.

    grafik

    When immidately drawing the text, alignment is correct

    ax.annotate('Text', xy=(0.5, 0.6), xytext=xytext, arrowprops=dict(arrowstyle="]->", color='magenta'), ha='center', va='center')
    

    grafik

    It's not just text extent, the overall position is not updated as well, as we can see when the inital xytext does not coincide with the text that is later added

    # modified line in original example:
    ann = ax.annotate('', xy=(0.5, 0.6), xytext=(0.5, 0.5), arrowprops=dict(arrowstyle="]->"))
    

    grafik

  3. dikshajangra12918-oss commented on Mar 31, 2026

    @dikshajangra12918-oss
    Contributor

    It seems like the arrow position is correctly computed at creation time but not updated when the text or its extent changes later.
    Would it make sense to trigger a recomputation of the arrow position after seting patchA, based on the current text extent?
    Or is there a design reason why annotation does not update in the same way as FancyArrowPatch here?

  4. timhoffm commented on Apr 1, 2026

    @timhoffm
    Member

    You are welcome to investigate. I project, nobody will be able to answer that question off the top of their head.

  5. timhoffm commented on Apr 8, 2026

    @timhoffm
    Member

    @Phlya why are you doing ax.annotate('', xy=(0.5, 0.6), xytext=xytext, arrowprops=dict(arrowstyle="->")) and then trying to patch in another text?

    This does not work as Annotation provides a text itself and "owns" the patchA of the associated arrow, i.e. it sets it at draw time to the bounding box of it's own text, which is empty in your case.

  6. Phlya commented on Apr 8, 2026

    @Phlya
    ContributorAuthor

    It does seem illogical, but I think the issue is that I couldn't find a way to get the bbox of the text patch and/or a way to modify it... It's been a few years since I wrote that though.

  7. Phlya commented on Apr 8, 2026

    @Phlya
    ContributorAuthor

    Ah, semi-scratch that (the above is also an issue, which prevents adjustText from using Annotation objects as input instead of Text).

    Looking into it a bit now, I think actually the idea is that I wanted to actually use the original provided Text objects and maintain all of their properties (fonts, colours, etc) since they are provided by the user, and not look for a way to replicate all of that when creating Annotation objects instead of the provided Texts.

  8. timhoffm commented on Apr 8, 2026

    @timhoffm
    Member

    Thanks for the clarification. So actually you want an arrow from "custom Artist" (your text object) to some point. That's what ConnectionPatch is for. Unfortunately it's currently less flexible than the transforms in Annotation, which makes it not yet a drop-in replacement, but the plan is to enhance that #26440.

  9. dikshajangra12918-oss commented on Apr 9, 2026

    @dikshajangra12918-oss
    Contributor

    Thanks for the clarification sir! I understand now that ConnectionPatch is the right long-term solution. I will look into issue #26440. Should I close this PR?

  10. timhoffm commented on Apr 12, 2026

    @timhoffm
    Member

    @dikshajangra12918-oss yes, please the related PR it's not the correct fix fox this scenario.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions