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
[Bug]: savefig() cannot save a PNG image 43200x21600 #26751
I am trying to plot some data on a map at high resolution, and I think I've come across a limit on the size of the image pyplot.savefig can save. When I save a 21600x10800 image, it works. However, when I try to save 43200x21600 image, it only saves half the image, always exactly half. According to my calculation, a 43200x21600 RGB image without any compression should occupy 2.6 GB, which is large but well within the 32 GB memory of my computer. I would like to know if a size limit is encoded somewhere for savefig, and if there's a way to bypass it. The image displays fine on my screen, just doesn't save to PNG.
Code for reproduction
frommatplotlibimportpyplotaspltimportnumpyasnp# make a checkerboard array of +1 and -1 for plottingA=np.zeros((90,180))
foriinrange(90):
forjinrange(180):
A[i,j] = (-1)**i* (-1)**j# create a large canvasfig=plt.figure(figsize=(24,12))
ax=plt.axes([0.,0.,1.,1.])
ax.axis('off')
# plot and saveax.imshow(A, vmin=-1, vmax=1, cmap=plt.cm.coolwarm, interpolation='none')
plt.savefig('image_43200.png', dpi=1800) # 24x12 inch image at 1800 dpi = 43200x21600
Actual outcome
No matter what I plot, savefig saves exactly half the image, always the left half. This is what the image looks like opened in GIMP.
Expected outcome
On screen, this is what the image looks like, which is correct. I would expect the saved image to look like this as well.
I will defer to experts on whether this is a duplicate of #26368 or not, but I see at least one difference between the two bugs. For #26368 the image does not render at all. For this bug, the image does render on the screen but doesn't save.
It doesn't save because you make it 18^2 =324 times larger when trying to save. Our backend Agg renderer has a limit of 2^15 = 32_768 pixels in each dimension, which your 24" side is violating.
I don't actually need to display that image interactively. If I simply need to create that image and save it to a PNG file, is there a way to not use Agg?
So... I just tried mplcairo, turns out that has size limitations as well. I don't know what that limit is, but when I tried to save the same image with the mplcairo backend, I got this error:
File ~/packages/macports/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/mplcairo/base.py:63, in GraphicsContextRendererCairo.__init__(self, width, height, dpi)
60 def __init__(self, width, height, dpi):
61 # Hide the overloaded constructors used by from_pycairo_ctx and
62 # _for_fmt_output.
---> 63 _mplcairo.GraphicsContextRendererCairo.__init__(
64 self, width, height, dpi)
65 RendererBase.__init__(self)
ValueError: invalid value (typically too big) for the size of the input (surface, pattern, etc.)
Larger images would require going into agg or cairo, forking them and upping the allowed sizes from 16 bits to 32 bits. Not impossible, but the use case is hard to understand. What are you planning to do with such a huge image?
Activity
scottshambaugh commentedon Sep 12, 2023
Thank you for reporting! This looks like a duplicate of #26368 to me, closing this thread to consolidate discussion over there.
AgilentGCMS commentedon Sep 12, 2023
I will defer to experts on whether this is a duplicate of #26368 or not, but I see at least one difference between the two bugs. For #26368 the image does not render at all. For this bug, the image does render on the screen but doesn't save.
jklymak commentedon Sep 12, 2023
It doesn't save because you make it 18^2 =324 times larger when trying to save. Our backend Agg renderer has a limit of 2^15 = 32_768 pixels in each dimension, which your 24" side is violating.
AgilentGCMS commentedon Sep 12, 2023
@jklymak Ah I see.
savefigshould raise an error instead of silently saving a wrong image?AgilentGCMS commentedon Sep 12, 2023
I don't actually need to display that image interactively. If I simply need to create that image and save it to a PNG file, is there a way to not use Agg?
oscargus commentedon Sep 12, 2023
You may want to try MPL-Cairo https://github.com/matplotlib/mplcairo
It seems like there are some limitations there as well, but it may work.
(Showing it or not is not really part of the equation as there are two different rendering processes and the really big one fails.)
AgilentGCMS commentedon Sep 16, 2023
So... I just tried
mplcairo, turns out that has size limitations as well. I don't know what that limit is, but when I tried to save the same image with themplcairobackend, I got this error:jklymak commentedon Sep 16, 2023
Larger images would require going into agg or cairo, forking them and upping the allowed sizes from 16 bits to 32 bits. Not impossible, but the use case is hard to understand. What are you planning to do with such a huge image?