scipy: savefig without frames, axes, only content

PythonImageNumpyMatplotlibScipy

Python Problem Overview


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

Python Solutions


Solution 1 - Python

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 - Python

An easier solution seems to be:

fig.savefig('out.png', bbox_inches='tight', pad_inches=0)

Solution 3 - Python

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 - Python

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

Solution 5 - Python

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)

Solution 6 - Python

This one work for me

plt.savefig('filename',bbox_inches='tight',transparent=True, pad_inches=0)

Solution 7 - Python

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)

Solution 8 - Python

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 )

Solution 9 - Python

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

Solution 10 - Python

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()

Solution 11 - Python

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 2x2 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')

Solution 12 - Python

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()

enter image description here

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJakub M.View Question on Stackoverflow
Solution 1 - PythonmatehatView Answer on Stackoverflow
Solution 2 - PythonweatherfrogView Answer on Stackoverflow
Solution 3 - PythonunutbuView Answer on Stackoverflow
Solution 4 - PythonCagri SarigozView Answer on Stackoverflow
Solution 5 - PythonMostafa PakparvarView Answer on Stackoverflow
Solution 6 - PythonCathy YangView Answer on Stackoverflow
Solution 7 - PythonKrackleView Answer on Stackoverflow
Solution 8 - PythonbreadstickView Answer on Stackoverflow
Solution 9 - PythonCloud ChoView Answer on Stackoverflow
Solution 10 - PythonGPrathapView Answer on Stackoverflow
Solution 11 - PythoncuriousView Answer on Stackoverflow
Solution 12 - PythonAtom ScottView Answer on Stackoverflow