scipy: savefig without frames, axes, only content
In numpy/scipy I have an image stored in an array. I can display it, I want to save it using savefig
without any borders, axes, labels, titles,... Just pure image, nothing else.
I want to avoid packages like PyPNG
or scipy.misc.imsave
, they are sometimes problematic (they do not always install well, only basic savefig()
for me
Solution 1:
EDIT
Changed aspect='normal
to aspect='auto'
since that changed in more recent versions of matplotlib (thanks to @Luke19).
Assuming :
import matplotlib.pyplot as plt
To make a figure without the frame :
fig = plt.figure(frameon=False)
fig.set_size_inches(w,h)
To make the content fill the whole figure
ax = plt.Axes(fig, [0., 0., 1., 1.])
ax.set_axis_off()
fig.add_axes(ax)
Then draw your image on it :
ax.imshow(your_image, aspect='auto')
fig.savefig(fname, dpi)
The aspect
parameter changes the pixel size to make sure they fill the figure size specified in fig.set_size_inches(…)
. To get a feel of how to play with this sort of things, read through matplotlib's documentation, particularly on the subject of Axes, Axis and Artist.
Solution 2:
An easier solution seems to be:
fig.savefig('out.png', bbox_inches='tight', pad_inches=0)
Solution 3:
You can find the bbox of the image inside the axis (using get_window_extent
), and use the bbox_inches
parameter to save only that portion of the image:
import numpy as np
import matplotlib.pyplot as plt
data=np.arange(9).reshape((3,3))
fig=plt.figure()
ax=fig.add_subplot(1,1,1)
plt.axis('off')
plt.imshow(data)
extent = ax.get_window_extent().transformed(fig.dpi_scale_trans.inverted())
plt.savefig('/tmp/test.png', bbox_inches=extent)
I learned this trick from Joe Kington here.
Solution 4:
I've tried several options in my case, and the best solution was this:
fig.subplots_adjust(bottom = 0)
fig.subplots_adjust(top = 1)
fig.subplots_adjust(right = 1)
fig.subplots_adjust(left = 0)
then save your figure with savefig