-
-
Notifications
You must be signed in to change notification settings - Fork 7.9k
Add an .annotate
method to Artist
#25094
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
An Annotation class is a FancyArrowPatch and a Text. This sounds like it could be a compound Artist like that, or even just an Annotation object, perhaps with more Text placement knobs, or a child class. I don't think FancyArrowPatch on its own should grow a text method, and it almost certainly should not be called |
Looking at fig, ax = plt.subplots(figsize=(3,3))
arr = mpatches.FancyArrowPatch((.25,.25), (.75,.75), arrowstyle='->,head_width=.15', mutation_scale=20, )
ax.add_patch(arr)
ax.annotate("label", (.5, .5), xycoords=arr, ha='center', va='center')
ax.set(xlim=(0,1), ylim=(0,1)) so maybe my actual issue is that def annotate(self, label, xy, **kwargs):
self.axes.annotate(label, xy, xycoords=self, **kwargs) which I know seems pointless but like I struggle w/ how to communicate and make discoverable all the things |
The core problem here is that we need all of those knobs. Reducing the number or changing the parameterization either throws out useful functionality or just masks the problem. I think we should take inspiration from https://docs.python.org/3/library/itertools.html#itertools-recipes and write up as functions a whole lot of these alternate paramaterization. Either they happen to be what users want (and then they can copy-paste and be done), the are close enough that users can tweak them a little bit, or they are extensive enough to provide inspiration for what the users actually need to write for them selves. |
Yeah I'm not suggesting we take any away from That being said, I think a # Annotating an Artist
# ====================
#
# Annotations can be positioned relative to an artist by setting the *xycoords* to the artist.
fig, ax = plt.subplots(figsize=(3,3))
arr = mpatches.FancyArrowPatch((.25,.25), (.75,.75), arrowstyle='->,head_width=.15', mutation_scale=20, )
ax.add_patch(arr)
ax.annotate("label", (.5, .5), xycoords=arr, ha='center', va='center')
ax.set(xlim=(0,1), ylim=(0,1)) |
Given that you just wrote the example can you please directly open the PR 😄 . |
.set_label
to FancyArrowPatch.annotate
method to Artist
See also #22223 (comment): I think the idea of having an easy way to specify coordinates in units relative to another artist's bounding box is something worth exploring. |
AFAIK, we don't have Artists that have functions to create and add other Artists to a figure/ axes. I'm hesitant to change this as this adds complexity to the Artist (for example the function would have to determine whether the parent artist is in an Axes or figure and behave accordingly) Also, |
I think draggable annotations would be really really cool, and is kinda what's happening in AnnotatedCursor I think. And more than that for me is the bookkeeping aspect, but maybe @jklymak's compound artist suggestion "AnnotatedArtist" suggestion would work for that? Basically, something like annotated_arrow = AnnotatedArtist(FancyArrowPatch)
annotated_arrow.add_annotation(...)
annotated_arrow.add_annotation(...) so that the complexity isn't in the artist? Granted, this is maybe more useful for something that's getting annotated a lot or something interactive/animated than my actual use case of annotating almost everything in a figure I'm making. |
Can draggable annotations not already be supported by draggable text? If you can just drag the annotation wherever you like, why would it need to be attached to a parent artist?
A lot of your use cases seem to be diagraming. I'm not against diagramming in Matplotlib per-se, but it's a bit orthogonal to the main point of Matplotlib - there are lots of great diagramming GUI-based programs in the world. |
That seems OK - Do we have an artist transform object - having that evaluated at draw time doesn't seem too hard. |
What currently happens if you set |
@jklymak I think that's close to my IndirectTransform proposal at #22223 (comment)? |
So ok, this is totally doable 😄 I'm not a fan of having to do the bookkeeping by hand, but I can live w/ that given the lack of enthusiasm. And @anntzer's IndirectTransform proposal would probably solve most of my other use cases, so I'll close in favor of that. |
I use
FancyArrowPatch
a lot to make diagrams and they have a lot of arrows and I'd really like tikz-like positioning of labels along the arrow. The arrow demo has an example of the sort of manual work that goes into trying to position each label correctly and it'd be nice to move all that positioning logic inside a method onFancyArrowPatch
.(Discussion of migrating arrow to vector and therefore FancyArrowPatch so it could take advantage is at #22435)
For this method, we can reuse the 'ha' and 'va' arguments relative to the line, w/ n additional offset argument (here relpos, but possibly something closer to the annotate api offset(xoffset, yoffset))
----->
label
label
maybe |--a1--[bbox]--a2-->
Originally posted by @story645 in #22223 (comment)
ETA: Based on the discussion below, where I've landed is that an
.annotate
method on artist would give me the bookkeeping I want - ease of keeping track of which annotation I put on what-and be fairly generalizable.with annotations I guess added as child artists/sibling artists -> do we have a mechanism for this?
The text was updated successfully, but these errors were encountered: