Les tracés Matplotlib: enlever les axes, les légendes et les espaces blancs

Je suis nouveau en Python et Matplotlib, je voudrais simplement appliquer colormap à une image et écrire l'image résultante, sans utiliser d'axes, d'étiquettes, de titres ou quoi que ce soit habituellement ajouté automatiquement par matplotlib. Voici ce que j'ai fait:

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)

il supprime avec succès l'axe de la figure, mais la figure sauvegardée présente un rembourrage blanc et un cadre autour de l'image réelle. Comment puis-je les enlever (au moins le rembourrage blanc)? Merci

163
demandé sur sunmat 2012-02-15 18:18:53

8 réponses

je pense que la commande axis('off') s'occupe d'un des problèmes plus succinctement que de changer chaque axe et la frontière séparément. Il laisse toujours l'espace blanc autour de la frontière. L'ajout de bbox_inches='tight' à la commande savefig vous y mène presque, vous pouvez voir dans l'exemple ci-dessous que l'espace blanc à gauche est beaucoup plus petit, mais encore présent.

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

221
répondu Hooked 2016-06-14 13:27:53

j'ai appris ce truc de matehat, ici :

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

rendements

enter image description here

70
répondu unutbu 2017-11-14 11:27:55

solution la plus simple Possible:

j'ai simplement combiné la méthode décrite dans la question et la méthode de la réponse par le Accroché.

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)

après ce code il n'y a pas d'espaces et pas de cadre.

No whitespaces, axes or frame

33
répondu Domagoj 2014-10-29 10:17:31

personne n'a mentionné imsave pourtant, ce qui en fait une seule doublure:

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

il stocke directement l'image telle qu'elle est, c'est-à-dire qu'il n'ajoute pas d'axes ou de bordure/rembourrage.

enter image description here

15
répondu luator 2017-09-19 06:57:48

vous pouvez également spécifier la portée de la figure à l'argument bbox_inches . Cela éliminerait le rembourrage blanc autour de la 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)
8
répondu Miguel de Val-Borro 2014-08-29 14:08:02

cela devrait enlever tout le rembourrage et les bordures:

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)
1
répondu Vlady Veselinov 2018-07-28 17:17:04

tout d'abord, pour certains formats d'image (i.e. TIFF ), vous pouvez enregistrer le colormap dans l'en-tête et la plupart des utilisateurs afficheront vos données avec le colormap.

pour sauvegarder une image réelle matplotlib , qui peut être utile pour ajouter des annotations ou d'autres données aux images, j'ai utilisé la solution suivante:

fig, ax = plt.subplots(figsize=inches)
ax.matshow(data)  # or you can use also imshow
# add annotations or anything else
# The code below essentially moves your plot so that the upper
# left hand corner coincides with the upper left hand corner
# of the artist
fig.subplots_adjust(left=0, right=1, top=1, bottom=0, wspace=0, hspace=0)
# now generate a Bbox instance that is the same size as your
# single axis size (this bbox will only encompass your figure)
bbox = matplotlib.transforms.Bbox(((0, 0), inches))
# now you can save only the part of the figure with data
fig.savefig(savename, bbox_inches=bbox, **kwargs)
0
répondu David Hoffman 2017-12-27 21:58:12

j'ai aimé ubuntu réponse, mais il ne montre pas explicitement comment définir la taille de la non-images carrées out-of-the-box, alors je l'ai modifié pour faciliter le copier-coller:

import matplotlib.pyplot as plt
import matplotlib.image as mpimg
import numpy as np

def save_image_fix_dpi(data, dpi=100):
    shape=np.shape(data)[0:2][::-1]
    size = [float(i)/dpi for i in shape]

    fig = plt.figure()
    fig.set_size_inches(size)
    ax = plt.Axes(fig,[0,0,1,1])
    ax.set_axis_off()
    fig.add_axes(ax)
    ax.imshow(data)
    fig.savefig('out.png', dpi=dpi)
    plt.show()

sauvegarder des images sans bordure est facile quel que soit le dpi que vous choisissez si pixel_size/dpi=size est conservé.

data = mpimg.imread('test.png')
save_image_fix_dpi(data, dpi=100)

enter image description here

cependant l'affichage est effrayant. Si vous choisissez un petit dpi, votre taille d'image peut être plus grande que votre écran et vous obtenez la bordure pendant l'affichage. Néanmoins, cela n'affecte pas l'enregistrement.

Donc, pour

save_image_fix_dpi(data, dpi=20)

l'affichage devient bordé (mais l'économie fonctionne): enter image description here

0
répondu csnemes 2018-03-09 13:25:52