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
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 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.
Method 2
An easier solution seems to be:
fig.savefig('out.png', bbox_inches='tight', pad_inches=0)
Method 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.
Method 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
Method 5
For anybody trying to do this in Jupyter
plt.axis('off')
spec = plt.imshow
plt.savefig('spec',bbox_inches='tight',transparent=True, pad_inches=0)
Method 6
This one work for me
plt.savefig('filename',bbox_inches='tight',transparent=True, pad_inches=0)
Method 7
I will suggest heron13 answer with a slight addition borrowed from here to remove the padding left after setting the bbox to tight mode, therefore:
axes = fig.axes()
axes.get_xaxis().set_visible(False)
axes.get_yaxis().set_visible(False)
fig.savefig('out.png', bbox_inches='tight', pad_inches=0)
Method 8
Actually I have tried this recently and instead of all these lines, you can use
plt.imsave(image_path, image)
Works like a charm. just one line and problem solved.
imsave()
Documentation ( https://matplotlib.org/3.1.1/api/_as_gen/matplotlib.pyplot.imsave.html )
Method 9
For me, this code made similar the input image size without frame and axes. I combined snippets from matehat, unutbu, and WHZW:
fig = plt.figure()
ax = fig.add_subplot(1,1,1)
plt.axis('off')
viridis = cm.get_cmap('gist_gray', 256)
plt.imshow(data, aspect='auto', cmap=viridis)
plt.tight_layout()
plt.savefig(out_file, bbox_inches='tight', transparent=True, pad_inches=0)
Runtime environment:
Python: 3.6.10
Matplotlib: 3.2.1
OS: Windows 10
Method 10
I had the same problem while doing some visualization using librosa where I wanted to extract content of the plot without any other information. So this my approach. unutbu answer also helps me to make to work.
figure = plt.figure(figsize=(500, 600), dpi=1)
axis = plt.subplot(1, 1, 1)
plt.axis('off')
plt.tick_params(axis='both', left='off', top='off', right='off', bottom='off', labelleft='off', labeltop='off',
labelright='off', labelbottom='off')
# your code goes here. e.g: I used librosa function to draw a image
result = np.array(clip.feature_list['fft'].get_logamplitude()[0:2])
librosa.display.specshow(result, sr=api.Clip.RATE, x_axis='time', y_axis='mel', cmap='RdBu_r')
extent = axis.get_window_extent().transformed(figure.dpi_scale_trans.inverted())
plt.savefig((clip.filename + str("_.jpg")), format='jpg', bbox_inches=extent, pad_inches=0)
plt.close()
Method 11
While the above answers address removing margins and padding, they did not work for me in removing labels. Here’s what worked, for anyone who stumbles upon this question later:
Assuming you want a 2×2 grid of subplots from four images stored in images:
matplotlib.pyplot.figure(figsize = (16,12)) # or whatever image size you require
for i in range(4):
ax = matplotlib.pyplot.subplot(2,2,i+1)
ax.axis('off')
imshow(images[i])
matplotlib.pyplot.savefig(path, bbox_inches='tight')
Method 12
I tried to get rid of the border too, using tips here but nothing really worked.
Some fiddling about and I found that changing the faceolor gave me no border in jupyter labs (Any color resulted in getting rid of the white border).
Hope this helps.
def show_num(data): data = np.rot90(data.reshape((16,16)), k=3) data = np.fliplr(data) fig = plt.figure(frameon=False, facecolor='white') ax = plt.Axes(fig, [0., 0., 1., 1.]) ax.set_axis_off() fig.add_axes(ax) ax.imshow(data) plt.show()
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0
