You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
bbox images do not get placed properly when figure is saved to png or pdf #3918
When I create a figure using bbox images, everything looks fine, but when I save the figure, the images move. Here is an example
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.image import BboxImage
from matplotlib.transforms import Bbox, TransformedBbox
#Generate the image
im = np.random.rand(10, 10) * 255.0
#Set up figure
fig = plt.figure()
ax = fig.add_axes([0.1,0.1,0.8,0.8])
ax.set_xlim(-2,24)
ax.set_ylim(0,10)
#Create image that transforms automatically
bbox1 = Bbox.from_extents([0,0,10,10])
trans_bbox1 = TransformedBbox(bbox1, ax.transData)
bbox_image1 = BboxImage(trans_bbox1)
bbox_image1.set_data(im)
ax.add_image(bbox_image1)
#Create image that does not transform
bbox2 = Bbox.from_extents([12,0,22,10])
trans_bbox2 = bbox2.transformed(ax.transData)
bbox_image2 = BboxImage(trans_bbox2)
bbox_image2.set_data(im)
ax.add_image(bbox_image2)
#Save the result
fig.savefig('png_test.png')
fig.savefig('pdf_test.pdf')
If I take a screenshot of the figure window, it looks like this
which is what I expect. However, when I look at the 'png_test.png', the second image that did not use the TransformedBbox moves, as shown below
In the pdf, both images move, as shown below
In case it matters, I am using the Qt4Agg interactive backend with the Spyder IDE. My matplotlib version is 1.4.0.
I think the issue is that you are specifying the bounding box locations in display units. The transformation from data -> display takes into account things like the final dpi (which is one of the main reasons that the transform system exists).
In particular #2831 (comment) has a work-around that should solve your problem short of a complete overhaul of how the rendering backends work.
@tacaswell Thanks for the suggestion. The figure dpi and the savefig dpi were different and that fixed the png issue. (I have never understood why the figure dpi and savefig dpi do not default to the same values.) I tried to incorporate leejjoon's #2831 (comment) to fix the pdf problem, but I am not sure how to do it without an annotation. Doesn't the TransformedBbox that I used above do the same thing anyways?
The problem I am seeing might be the same as #2831, but I believe there is something different here. Check out the following example,
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.image import BboxImage
from matplotlib.transforms import Bbox, TransformedBbox
import matplotlib as mpl
mpl.rcParams['savefig.dpi'] = mpl.rcParams['figure.dpi']
im = np.random.rand(10, 10) * 255.0
#Set up figure
fig = plt.figure()
ax = fig.add_axes([0.1,0.1,0.8,0.8])
ax.set_xlim(-2,24)
ax.set_ylim(0,10)
#Create an image that transforms automatically
bbox1 = Bbox.from_extents([0,0,10,10])
trans_bbox1 = TransformedBbox(bbox1, ax.transData)
bbox_image1 = BboxImage(trans_bbox1, data = im)
ax.add_image(bbox_image1)
#Save the result
fig.savefig('pdf_test_with_1_image.pdf')
#Add another image that transforms automatically
bbox2 = Bbox.from_extents([12,0,22,10])
trans_bbox2 = TransformedBbox(bbox2, ax.transData)
bbox_image2 = BboxImage(trans_bbox2, data = im)
ax.add_image(bbox_image2)
#Save the result
fig.savefig('pdf_test_with_2_images.pdf')
The pdf with only one image looks correct:
When I add a second image, the figure window looks like this ,
but when I save it to a pdf, it looks all wrong:
The first image gets moved, and the second image is gone. Something happens in the pdf backend when I have two Bbox images that does not occur when I have one Bbox image.
@tacaswell can I ask you to take a look at my post above? I think my issue is not quite a duplicate of issue #2831. When I use TransformedBbox with one image, the PDF looks fine. When I use TransformedBbox with two images, the PDF gets messed up.
I modified your example a little bit. I flipped the second image: bbox_image2 = BboxImage(trans_bbox2, data = im[::-1]). When running this example, we see that the second image is getting placed on top of the first. So, the second image is using the first image's transform (in the file, that is). I can also verify that this problem occurs when saving the results as 'eps' files.
@WeatherGod, thanks for confirming the bug. It appears that, no matter where I place the two images, they both get moved to the lower left corner of the axes when the figure is saved as a pdf.
For example, here is the matplotlib figure window:
and here is an image of the pdf file:
Oh, now that's interesting! It is as if none of the transform data is being
utilized!
On Jan 20, 2015 8:50 PM, "Benjamin Reedlunn" notifications@github.com
wrote:
@WeatherGodhttps://github.com/WeatherGod, thanks for confirming the
bug. It appears that, no matter where I place the two images, they both get
moved to the lower left corner of the axes when the figure is saved as a
pdf.
This issue has been marked "inactive" because it has been 365 days since the last comment. If this issue is still present in recent Matplotlib releases, or the feature request is still wanted, please leave a comment and this label will be removed. If there are no updates in another 30 days, this issue will be automatically closed, but you are free to re-open or create a new issue if needed. We value issue reports, and this procedure is meant to help us resurface and prioritize issues that have not been addressed yet, not make them disappear. Thanks for your help!
@tacaswell how do you know this issue is resolved? When I try to run the code in my Dec 13, 2014 post, I get the following error: TypeError: 'image' must be an instance of matplotlib.image.AxesImage, not a matplotlib.image.BboxImage. I tried swapping out BboxImage for AxesImage, but that gave a different error.
Thanks, tacaswell. Running the code in my Dec 13, 2014 post, except with ax.add_image -> ax.add_artist, allows me to confirm the issue is fixed with matplotlib 3.7. Yay! The first image moves ever so slightly when I save two images in the same set of axes, but I think it is negligible for most purposes.
Activity
tacaswell commentedon Dec 13, 2014
See the discussion in #2831.
I think the issue is that you are specifying the bounding box locations in display units. The transformation from data -> display takes into account things like the final dpi (which is one of the main reasons that the transform system exists).
In particular #2831 (comment) has a work-around that should solve your problem short of a complete overhaul of how the rendering backends work.
breedlun commentedon Dec 14, 2014
@tacaswell Thanks for the suggestion. The figure dpi and the savefig dpi were different and that fixed the png issue. (I have never understood why the figure dpi and savefig dpi do not default to the same values.) I tried to incorporate leejjoon's #2831 (comment) to fix the pdf problem, but I am not sure how to do it without an annotation. Doesn't the
TransformedBboxthat I used above do the same thing anyways?The problem I am seeing might be the same as #2831, but I believe there is something different here. Check out the following example,
The pdf with only one image looks correct:

,

When I add a second image, the figure window looks like this
but when I save it to a pdf, it looks all wrong:
The first image gets moved, and the second image is gone. Something happens in the pdf backend when I have two Bbox images that does not occur when I have one Bbox image.
breedlun commentedon Dec 16, 2014
@tacaswell can I ask you to take a look at my post above? I think my issue is not quite a duplicate of issue #2831. When I use
TransformedBboxwith one image, the PDF looks fine. When I useTransformedBboxwith two images, the PDF gets messed up.WeatherGod commentedon Jan 20, 2015
I modified your example a little bit. I flipped the second image:
bbox_image2 = BboxImage(trans_bbox2, data = im[::-1]). When running this example, we see that the second image is getting placed on top of the first. So, the second image is using the first image's transform (in the file, that is). I can also verify that this problem occurs when saving the results as 'eps' files.breedlun commentedon Jan 21, 2015
@WeatherGod, thanks for confirming the bug. It appears that, no matter where I place the two images, they both get moved to the lower left corner of the axes when the figure is saved as a pdf.
For example, here is the matplotlib figure window:


and here is an image of the pdf file:
WeatherGod commentedon Jan 21, 2015
Oh, now that's interesting! It is as if none of the transform data is being
utilized!
On Jan 20, 2015 8:50 PM, "Benjamin Reedlunn" notifications@github.com
wrote:
tacaswell commentedon Jan 21, 2015
attn @jenshnielsen
12 remaining items
github-actions commentedon Mar 9, 2023
This issue has been marked "inactive" because it has been 365 days since the last comment. If this issue is still present in recent Matplotlib releases, or the feature request is still wanted, please leave a comment and this label will be removed. If there are no updates in another 30 days, this issue will be automatically closed, but you are free to re-open or create a new issue if needed. We value issue reports, and this procedure is meant to help us resurface and prioritize issues that have not been addressed yet, not make them disappear. Thanks for your help!
tacaswell commentedon Mar 9, 2023
This now works, however I have not bisected back to when it was fixed.
breedlun commentedon Mar 9, 2023
@tacaswell how do you know this issue is resolved? When I try to run the code in my Dec 13, 2014 post, I get the following error:
TypeError: 'image' must be an instance of matplotlib.image.AxesImage, not a matplotlib.image.BboxImage. I tried swapping out BboxImage for AxesImage, but that gave a different error.tacaswell commentedon Mar 9, 2023
I ran this with 3.6 when that was just a warning. Change
ax.add_image->ax.add_artist.breedlun commentedon Mar 11, 2023
Thanks, tacaswell. Running the code in my Dec 13, 2014 post, except with
ax.add_image->ax.add_artist, allows me to confirm the issue is fixed with matplotlib 3.7. Yay! The first image moves ever so slightly when I save two images in the same set of axes, but I think it is negligible for most purposes.