I use savefig
from Matplotlib to get an Image from a figure, and this image is modified with PIL after that. I also want to remove every padding.
My problem is that the final size of the image is smaller than expected. For example:
- Size = (8, 10)
- DPI = 300
- We expect a width of 300*8=2400
- But we get a width of 2310
Following this link (https://stackoverflow.com/a/24399985/374458) I've added plt.tight_layout()
and it works better. But the size is still smaller than expected. I think it's because of the padding which is not 0 before calling savefig
(pad_inches default seems to be 0.1).
How can a get an image with the right size?
Here is a code sample:
from PIL import Image
import matplotlib.pyplot as plt
import io
SIZE_X = 8
SIZE_Y = 10
IMAGE_DPI = 300
fig, ax = plt.subplots(figsize=(SIZE_X, SIZE_Y), dpi=IMAGE_DPI)
ax.set_axis_off()
ax.plot([1, 2, 3, 4])
buffer = io.BytesIO()
plt.tight_layout()
plt.savefig(buffer, dpi=IMAGE_DPI, ax=ax, format='png', bbox_inches='tight', pad_inches=0, transparent=True)
buffer.seek(0)
image = Image.open(buffer)
print('Expected: ', (SIZE_X * IMAGE_DPI, SIZE_Y * IMAGE_DPI))
print('Figure size: ', (fig.get_figwidth() * fig.get_dpi(), fig.get_figheight() * fig.get_dpi()))
print('Image Size: ', image.size)
plt.close(fig)
del fig
del buffer
Output:
Expected: (2400, 3000)
Figure size: (2400.0, 3000.0)
Image Size: (2310, 2910)
NB: With the code below I get the right image size but I don't manage to make transparency work.
image = Image.frombytes("RGBA", fig.canvas.get_width_height(), bytes(fig.canvas.get_renderer().buffer_rgba()))