Matplotlib plots: removing axis, legends and white spaces

Posted on

Question :

Matplotlib plots: removing axis, legends and white spaces

I’m new to Python and Matplotlib, I would like to simply apply colormap to an image and write the resulting image, without using axes, labels, titles or anything usually automatically added by matplotlib. Here is what I did:

def make_image(inputname,outputname):
    data = mpimg.imread(inputname)[:,:,0]
    fig = plt.imshow(data)
    fig.set_cmap('hot')
    fig.axes.get_xaxis().set_visible(False)
    fig.axes.get_yaxis().set_visible(False)
    plt.savefig(outputname)

It successfully removes the axis of the figure, but the figure saved presents a white padding and a frame around the actual image.
How can I remove them (at least the white padding)? Thanks

Asked By: sunmat

||

Answer #1:

I think that the command axis('off') takes care of one of the problems more succinctly than changing each axis and the border separately. It still leaves the white space around the border however. Adding bbox_inches='tight' to the savefig command almost gets you there, you can see in the example below that the white space left is much smaller, but still present.

Note that newer versions of matplotlib may require bbox_inches=0 instead of the string 'tight' (via @episodeyang and @kadrach)

from numpy import random
import matplotlib.pyplot as plt

data = random.random((5,5))
img = plt.imshow(data, interpolation='nearest')
img.set_cmap('hot')
plt.axis('off')
plt.savefig("test.png", bbox_inches='tight')

enter image description here

Answered By: Hooked

Answer #2:

I learned this trick from matehat, here:

import matplotlib.pyplot as plt
import numpy as np

def make_image(data, outputname, size=(1, 1), dpi=80):
    fig = plt.figure()
    fig.set_size_inches(size)
    ax = plt.Axes(fig, [0., 0., 1., 1.])
    ax.set_axis_off()
    fig.add_axes(ax)
    plt.set_cmap('hot')
    ax.imshow(data, aspect='equal')
    plt.savefig(outputname, dpi=dpi)

# data = mpimg.imread(inputname)[:,:,0]
data = np.arange(1,10).reshape((3, 3))

make_image(data, '/tmp/out.png')

yields

enter image description here

Answered By: unutbu

Answer #3:

Possible simplest solution:

I simply combined the method described in the question and the method from the answer by Hooked.

fig = plt.imshow(my_data)
plt.axis('off')
fig.axes.get_xaxis().set_visible(False)
fig.axes.get_yaxis().set_visible(False)
plt.savefig('pict.png', bbox_inches='tight', pad_inches = 0)

After this code there is no whitespaces and no frame.

No whitespaces, axes or frame

Answered By: Domagoj

Answer #4:

No one mentioned imsave yet, which makes this a one-liner:

import matplotlib.pyplot as plt
import numpy as np

data = np.arange(10000).reshape((100, 100))
plt.imsave("/tmp/foo.png", data, format="png", cmap="hot")

It directly stores the image as it is, i.e. does not add any axes or border/padding.

enter image description here

Answered By: luator

Answer #5:

You can also specify the extent of the figure to the bbox_inches argument. This would get rid of the white padding around the figure.

def make_image(inputname,outputname):
    data = mpimg.imread(inputname)[:,:,0]
    fig = plt.imshow(data)
    fig.set_cmap('hot')
    ax = fig.gca()
    ax.set_axis_off()
    ax.autoscale(False)
    extent = ax.get_window_extent().transformed(plt.gcf().dpi_scale_trans.inverted())
    plt.savefig(outputname, bbox_inches=extent)
Answered By: gypaetus

Answer #6:

This should remove all padding and borders:

from matplotlib import pyplot as plt

fig = plt.figure()
fig.patch.set_visible(False)

ax = fig.add_subplot(111)

plt.axis('off')
plt.imshow(data)

extent = ax.get_window_extent().transformed(fig.dpi_scale_trans.inverted())
plt.savefig("../images/test.png", bbox_inches=extent)
Answered By: Vlady Veselinov

Answer #7:

I found that it is all documented…

https://matplotlib.org/3.1.1/api/_as_gen/matplotlib.axes.Axes.axis.html#matplotlib.axes.Axes.axis

My codeā€¦. “bcK” is a 512×512 image

plt.figure()
plt.imshow(bck)
plt.axis("off")   # turns off axes
plt.axis("tight")  # gets rid of white border
plt.axis("image")  # square up the image instead of filling the "figure" space
plt.show()
Answered By: paulj

Answer #8:

The upvoted answer does not work anymore. To get it to work you need
to manually add an axis set to [0, 0, 1, 1], or remove the patch under figure.

import matplotlib.pyplot as plt

fig = plt.figure(figsize=(5, 5), dpi=20)
ax = plt.Axes(fig, [0., 0., 1., 1.])
fig.add_axes(ax)
plt.imshow([[0, 1], [0.5, 0]], interpolation="nearest")
plt.axis('off')                                # same as: ax.set_axis_off()

plt.savefig("test.png")

Alternatively, you could just remove the patch. You don’t need to add a subplot in order to remove the paddings. This is simplified from Vlady’s answer below

fig = plt.figure(figsize=(5, 5))
fig.patch.set_visible(False)                   # turn off the patch

plt.imshow([[0, 1], [0.5, 0]], interpolation="nearest")
plt.axis('off')

plt.savefig("test.png", cmap='hot')

This is tested with version 3.0.3 on 2019/06/19. Image see bellow:

enter image description here

A much simpler thing to do is to use pyplot.imsave. For details, see luator’s answer bellow

Answered By: episodeyang

Leave a Reply

Your email address will not be published.