Inset axes anchored to specific points in data coordinates?
Asked Answered
L

1

6

I'd like to be able to overlay multiple inset axes on top of a set of parent axes, something like this:

enter image description here

Ideally, I'd like the anchor point of each set of inset axes to be fixed in data coordinates, but for the x,y extent of the axes to scale with figure size rather than the scale of the data.

For example, if I zoomed in on a region in the parent axes, I'd want the positions of the inset axes to move together with the data plotted in the parent axes, but for their areas and aspect ratios to stay the same. The exact behaviour I'm looking for is something similar to a plot marker or a matplotlib.Annotation instance. However, I'd settle for just being able to set the extent of the axes in data coordinates.

I'm aware that I can pass the rect argument to axes() to specify the position and extent in normalized figure coordinates. However, I need my axes to be anchored to specific points in data coordinates.

I've also tried doing something like this:

from matplotlib import pyplot as pp

fig,parent_ax = pp.subplots(1,1)
parent_ax.set_xlim(0,1)
parent_ax.set_ylim(0,1)

# desired axis bounding box in data coordinates
rect = (0.1,0.2,0.2,0.3)

child_ax = axes(rect)

# apply transformation to data coordinates of parent axis
child_ax.set_transform(parent_ax.transData)

which doesn't have the desired effect (the x,y limits of my child axis are now coupled to those of the parent axis, which I don't want, and its position is still not in data coordinates).

I've also looked at the various examples here, but none of them seem to do quite what I'm looking for, i.e. allow me to specify an arbitrary anchor point in data coordinates.

Any ideas?

Lawrence answered 12/10, 2013 at 15:27 Comment(7)
Have you seen matplotlib.org/mpl_toolkits/axes_grid/users/… and the section below it on the same page? They might be what you want, but I don't understand what you want and what they do well enough to be sure.Unemployment
failing that, I think you will have to write a couple of call backs. I would suggest grabbing onto the draw_event and on every draw relocate/rescale everything as you want.Unemployment
@tcaswell They're close, but not quite what I'm looking for - "artist need to be drawn in the canvas coordinate", whereas I need to position the child axes in data coordinates. For that reason, the loc= spec for positioning AxisArtists etc. is not useful to me. I'm still keen to avoid writing complicated callbacks to do something that seems like it ought to be possible using transformations.Lawrence
good luck! Digging into the mpl_toolkit code might give you some guidance, even if it doesn't work out of the box.Unemployment
I am still trying to sort out exactly what you are trying to do. You want the inset axes to move if you pan the main axes?Unemployment
@tcaswell Yes - they should remain anchored in fixed positions relative to my data when I pan and zoom. However, I'd like their area/aspect ratio to remain constant when I zoom. In other words I want them to behave a bit like plot markers, annotation classes etc. That's where I'm currently looking for a solution.Lawrence
The more I think about it the more I think building a call back is the right thing to do (I think you can do it with only one hooked up to draw_event with a sensible short-circut to prevent infinite loops). What you want is some what orthogonal to the way the library is designed.Unemployment
E
0

Save the inset axes as images and then insert them in the larger figure. See Adding a small photo/image to a large graph in Matplotlib/Python .

Elnaelnar answered 17/4, 2015 at 2:52 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.