2012-02-15 12 views
128

Sono nuovo di Python e Matplotlib, vorrei semplicemente applicare colormap a un'immagine e scrivere l'immagine risultante, senza utilizzare assi, etichette, titoli o qualsiasi cosa di solito aggiunta automaticamente di matplotlib. Ecco quello che ho fatto:Grafici Matlotlib: rimozione di assi, legende e spazi bianchi

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) 

Rimuove con successo l'asse della figura, ma la figura salvato presenta un'imbottitura bianca e una cornice intorno all'immagine reale. Come posso rimuoverli (almeno il padding bianco)? Grazie

+0

Tutte le soluzioni di questo oggetto si sono focalizzate su 'imshow'. Se disponi di un grafico a dispersione, la seguente risposta potrebbe aiutarti: http://stackoverflow.com/a/40727744/4124317 – ImportanceOfBeingErnest

+0

Questa domanda è attualmente il secondo risultato di una ricerca su Google di 'matplotlib'. – onewhaleid

risposta

176

Credo che il comando axis('off') si prende cura di uno dei problemi più succinto che cambiare ogni asse e le confine separatamente. Tuttavia, lascia comunque lo spazio bianco attorno al bordo. L'aggiunta di bbox_inches='tight' al comando savefig ti fa quasi arrivare lì, puoi vedere nell'esempio seguente che lo spazio bianco rimasto è molto più piccolo, ma ancora presente.

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

+3

Seguendo il suggerimento di unutbu, potresti usare 'fig = plt.figure()', 'ax = plt.axes ([0,0,1,1])', quindi 'plt.imshow (data, interpolation =" nearest " 'Combinato con' plt.axis ("off") ', dovrebbe sbarazzarsi di tutto accanto all'immagine stessa, si spera! – PhilMacKay

+1

Combinare i metodi della domanda ({fig.axes.get_xaxis(). Set_visible (False) & fig.axes.get_yaxis(). set_visible (False)} con {plt.axis ('off')}) ha risolto il problema per me. (Non ci sono più spazi bianchi) E non dimenticare di impostare {pad_inches} in savefig su 0 – Domagoj

+2

Mi sono imbattuto in questo problema, nessuna delle soluzioni in questo thread e quelle collegate ha funzionato, tuttavia specificare esplicitamente 'bbox_inches = 0' ha fatto il trucco. – kadrach

62

ho imparato questo trucco da 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') 

rendimenti

enter image description here

+2

Sono abbastanza sicuro che tu abbia la risposta corretta (anche se probabilmente c'è più di un modo per farlo), ma mi chiedo se puoi spiegare * perché * è la risposta giusta? E il tuo codice rimuove lo spazio bianco? – Yann

+0

Seguendo il link, trovo una risposta a quello che mi stavo chiedendo ... – Yann

+3

@Yann, oltre alla documentazione, trovo molto utile commentare una riga alla volta per vedere quale effetto ha ogni comando. È il modo empirico! – unutbu

7

È inoltre possibile specificare l'entità della cifra all'argomento bbox_inches. Ciò eliminerebbe l'imbottitura bianca attorno alla figura.

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

Possibile soluzione più semplice:

ho semplicemente unito il metodo descritto nella domanda e il metodo della risposta da 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) 

Dopo questo codice non ci sono spazi bianchi e nessuna cornice.

No whitespaces, axes or frame

+2

Il tuo metodo ha rimosso tutti gli spazi bianchi intorno a questa immagine, buon lavoro, ma non so ancora perché aggiungere il comando 'fig.axes.get_xaxis(). set_visible (False)' risolve il problema. Grazie – ollydbg23

+3

Sì, se non chiami questo comando la maggior parte degli spazi bianchi sarà rimossa. Tuttavia nel mio caso c'erano ancora alcuni spazi tra la mia trama e il bordo dell'immagine .png (forse 2px di larghezza). Chiamando i seguenti comandi mi sono sbarazzato di quegli spazi testardi. – Domagoj

+3

Nota, tuttavia, che quanto sopra non funzionerà in presenza di più assi nella stessa figura (nel mio caso un'immagine incorporata nella trama). Soluzione: 'fig.axes [0]', e in generale tutti gli assi o selezionati. –

9

Nessuno menzionato imsave ancora, che rende questa una battuta:

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

Memorizza direttamente l'immagine così com'è, cioè non aggiunge alcun assi o confine/imbottitura.

enter image description here

0

In primo luogo, per alcuni formati di immagine (vale a dire TIFF) si può effettivamente salvare la mappa di colori nell'intestazione e la maggior parte degli spettatori mostrerà i dati con la mappa colori.

Per salvare un'immagine reale matplotlib, che può essere utile per aggiungere annotazioni o altri dati di immagini, ho usato la seguente soluzione:

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

mi piaceva ubuntu's risposta, ma non è stato attestanti in modo esplicito come impostare le dimensioni per le immagini non quadrati out-of-the-box, per cui ho modificato per semplice copia-incolla:

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

Salvataggio di immagini senza bordo è facile qualunque dpi si sceglie se pixel_size/dPI = la dimensione è mantenuta.

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

enter image description here

Tuttavia la visualizzazione è spettrale. Se si sceglie la risoluzione ridotta, la dimensione dell'immagine può essere maggiore dello schermo e si ottiene il bordo durante la visualizzazione. Tuttavia, questo non influisce sul risparmio.

Così per

save_image_fix_dpi(data, dpi=20) 

Il display viene delimitato (ma opere di risparmio): enter image description here

Problemi correlati