Reputation: 1660
I don't understand the definition of axes.bbox
. For example:
>>> import matplotlib.pyplot as plt
>>> f, ax = plt.subplots()
>>> ax.bbox
TransformedBbox(Bbox('array([[ 0.125, 0.1 ],\n [ 0.9 , 0.9 ]])'), BboxTransformTo(TransformedBbox(Bbox('array([[ 0., 0.],\n [ 8., 6.]])'), Affine2D(array([[ 80., 0., 0.],
[ 0., 80., 0.],
[ 0., 0., 1.]])))))
What do these values mean? I would have assumed that 4 numbers would be sufficient to define a rectangle. Obviously more information is stored here.
For the commands like ax.figure.canvas.blit(bbox)
I need to define a value for the bbox. How can I manually define a bbox
of particular dimensions (let's say for the lower right quarter of the axes)?
Upvotes: 17
Views: 46018
Reputation: 20344
The value you see displayed is a bit of a complicated Bbox
, with nested transforms that it automatically applies. Firstly, it is a TransformedBbox
instance - quoting from the docs:
A Bbox that is automatically transformed by a given transform.
the representation of it in the console that you show above displays two things (comma separated) - the main Bbox
upon which it is based, and the transform
that it applies. The transform
in this case is a BboxTransformTo
object, which:
BboxTransformTo is a transformation that linearly transforms points from the unit bounding box to a given Bbox.
In your case, the transform
itself is based upon a TransformedBBox
which again has a Bbox
upon which it is based and a transform - for this nested instance an Affine2D
transform.
The purpose of the transforms (I believe) is to translate from relative co-ordinates to screen units.
In your example, you might find that the points you expected to see are given by
>>> ax.bbox.get_points()
array([[ 80., 48.],
[ 576., 432.]])
All the code for this is in available on github if you want to convince yourself exactly what is being displayed.
From the documentation, you can instantiate a Bbox object with the four numbers you imagine, e.g.
from matplotlib.transforms import Bbox
my_blit_box = Bbox(np.array([[x0,y0],[x1,y1]])
You could also use one of the static methods, e.g.
my_blit_box = Bbox.from_bounds(x0, y0, width, height)
I haven't got your use case, so can't say whether rolling your own Bbox
and passing it to blit()
will work directly for your case.
However, it's likely to be a really complicated way round to do what you want.
Assming that you want to animate a plot - you can usually pass blit=True
in as an argument to the animation functions and they will sort this out themselves. The docs are here. There are some examples here, including ones with subplots. As a skeleton - you might do something like
fig = plt.figure()
ax1 = fig.add_subplot(1, 2, 1)
ax2 = fig.add_subplot(2, 2, 2)
ax3 = fig.add_subplot(2, 2, 4)
# Code to actually put data on your 3 axes
animation.TimedAnimation.__init__(self, fig, interval=50, blit=True)
If you want to refresh one subplot out of many - passing in the ax.bbox
directly into the blit
function should work.
Note that most of the examples given don't define their own Bbox, but rather pass in a Bbox derived from an axes
, figure
or canvas
into blit
. Note also that passing nothing into ax.figure.canvas.blit()
will redraw the whole canvas (the default option - although I can't see why you'd want to do that).
Upvotes: 17