Skip to content

[ENH]: Position artists (particularly Annotations) relative to multiple other artists #22223

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

Open
stanleyjs opened this issue Jan 12, 2022 · 3 comments

Comments

@stanleyjs
Copy link
Contributor

stanleyjs commented Jan 12, 2022

Problem

Currently we can position text relative to a single artist, as described in https://matplotlib.org/stable/tutorials/text/annotations.html?highlight=complex%20coordinate#using-complex-coordinates-with-annotations.

I would like to position texts relative to multiple artists. For instance, let's consider two text artists, txt1 positioned at (0.5,0.25) and txt2 (.5,0.75). Assume they are left-aligned and of width 0.1, so the left edge of each of their bbox is at 0.5, the right edge is at 0.6, and assume that txt2 at (.5,0.75) is top-aligned, so the top of its bbox is 0.75, and txt1 is bottom-aligned, so the bottom of its bbox is 0.25.

I would like some function combine_artists(txt1,txt2) that returns an object that combines the coordinate systems of txt1 and txt2 so that an artist can be positioned relative to the combined bbox. For instance, I would like to position some artist txt3 that is vertically centered between txt1 and txt2. Its data coordinate is (0.5,0.5), but its relative position coordinate in the combined txt1+txt2 space would be (0,0.5).

Proposed solution

There may already be a way to do this in the library, as it seems transforms are addable. What remains then is making the interface to creating the combined bbox/transform in a way that is easily accessible. I already tried just adding the transforms of the txt1 and txt2, which seemed like the most intuitive way for this to work.

@story645
Copy link
Member

story645 commented Jan 13, 2022

I think I 've wanted a variant of this for a while; adding a text labeling API to FancyArrowPatch to get tikz like labeling

ar = FancyArrowPatch
ar.set_label(str, pos={'over', 'under'. 'within'} , offset= ratio on interval of line, pad) #base off tikz api
over under within (default)
label
----->
----->
label
--label-->
relpos=0 relpos=1 relpos=.5 (default)
label-----> ----->label ---label--->

maybe |--a1--[bbox]--a2-->

@jklymak
Copy link
Member

jklymak commented Jan 13, 2022

I think this positioning style is only supported for annotations, so far as I know?

@anntzer
Copy link
Contributor

anntzer commented Jan 13, 2022

I think the first thing to do would actually to make this kind of coordinate systems generally available, rather than being special-cased in the Annotation API. Given that Annotations support arbitrary callables (although taking a renderer as arg, which we can't do for a plain Transform) I guess the general approach (of course, we can have more specific helpers, but let's think about the general case first) would be something like IndirectTransform(func: Callable[[], Transform]) and one would write e.g. IndirectTransform(lambda: BboxTranformTo(artist.get_window_extent())).

(Note, by the way, that some but not all implementations of get_window_extent currently default their renderer arg to figure._cachedRenderer; I think all should, for consistency and ease of use.)

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

No branches or pull requests

4 participants