Matplotlib kullanarak çizimi görüntülemek yerine resim dosyasına kaydedin


1150

Anında parseller oluşturmak için hızlı ve kirli bir senaryo yazıyorum. Aşağıdaki kodu ( Matplotlib belgelerinden) bir başlangıç ​​noktası olarak kullanıyorum:

from pylab import figure, axes, pie, title, show

# Make a square figure and axes
figure(1, figsize=(6, 6))
ax = axes([0.1, 0.1, 0.8, 0.8])

labels = 'Frogs', 'Hogs', 'Dogs', 'Logs'
fracs = [15, 30, 45, 10]

explode = (0, 0.05, 0, 0)
pie(fracs, explode=explode, labels=labels, autopct='%1.1f%%', shadow=True)
title('Raining Hogs and Dogs', bbox={'facecolor': '0.8', 'pad': 5})

show()  # Actually, don't show, just save to foo.png

Bir GUI üzerinde arsa görüntülemek istemiyorum, bunun yerine, örneğin bir toplu iş komut dosyalarında kullanılabilir, böylece arsa bir dosyaya (foo.png demek) kaydetmek istiyorum. Bunu nasıl yaparım?


85
Cevabı bulduğum anlaşılıyor: pylab.savefig ('foo.png')
Homunculus Reticulli

2
Bağlantı matplotlib.org'da bir yere bağlanabilir mi?
A.

40
Ayrıca pylab kullanılmıyorsa, şekil nesnesinin de bir savefigyöntemi vardır . Yani çağırabilir fig = plt.figure()sonra fig.savefig(...).
A.

27
Cevapların çoğu, plt.close(fig)büyük döngülerde özellikle önemli olan sayfayı aşağıya çeker. Aksi takdirde rakamlar açık kalır ve bellekte bekler ve tüm açık rakamlar yürütüldüğünde gösterilirplt.show()
timctran

nb: matplotlib.pyplot tercih edilir: stackoverflow.com/questions/11469336/…
ErichBSchulz

Yanıtlar:


1438

Soru cevaplanmış olsa da, matplotlib.pyplot.savefig kullanırken bazı yararlı ipuçları eklemek istiyorum . Dosya biçimi, uzantı tarafından belirtilebilir:

from matplotlib import pyplot as plt

plt.savefig('foo.png')
plt.savefig('foo.pdf')

Her ikisi de yararlı olabilecek sırasıyla rasterleştirilmiş veya vektörize bir çıktı verecektir. Ayrıca pylab, görüntünün etrafında cömert, genellikle istenmeyen bir boşluk bıraktığını göreceksiniz . Şunlarla kaldır:

savefig('foo.png', bbox_inches='tight')

9
Ortaya çıkan görüntünün boyutlarını değiştirmek mümkün müdür?
Llamageddon

43
@ Asmageddon dpi'yi plt.savefigdeğiştirebilirsiniz, cevaptaki bağlantıya bakın. Boyutlar şekil oluşturulurken kontrol edilebilir, bkz figsize. Matplotlib.org/api/figure_api.html#matplotlib.figure.Figure
Kancalı

5
@MoTSCHIGGE komutlarını kullanarak plt.ioff()etkileşimi devre dışı bırakabilirsiniz matplotlib.pyplot.
rubenvb

5
@STMohammed foo.png olan yolu. Örneğin, böyle bir dizine koyabilirsiniz savefig("mydir/foo.png").
Kancalı

3
bbox_inches = 'sıkı' bir cazibe gibi çalışır. Benim günümü yaptın
Catbuilts

205

Diğerlerinin söylediği gibi, plt.savefig()ya fig1.savefig()da gerçekten bir görüntüyü kaydetmenin yolu.

Ancak bazı durumlarda rakamın her zaman gösterildiğini gördüm . (örn. Spyder sahip plt.ion(): interaktif mod = Açık.) Dev döngümdeki şekil penceresinin kapanmasını plt.close(figure_object)( belgelere bakın ) zorlayarak bu sorunu gideririm , bu yüzden döngü sırasında bir milyon açık figürüm yok:

import matplotlib.pyplot as plt
fig, ax = plt.subplots( nrows=1, ncols=1 )  # create figure & 1 axis
ax.plot([0,1,2], [10,20,3])
fig.savefig('path/to/save/image/to.png')   # save the figure to file
plt.close(fig)    # close the figure window

Gerekirse figürü daha sonra tekrar açabilmelisiniz fig.show()(kendimi test etmedim).


9
Ayrıca ayarlayabilirsiniz plt.ioff() # turn of interactive plotting mode, ancak kodunuz bir hata ile çıkarsa kullanmak istediğiniz davranışı devre dışı bırakabilir.
Demis

2
Aynı sorunu Jupyter not defterlerinde de göreceksiniz. plt.close(fig)çözüldü
intsco


89

Bu bağlantıyı tam olarak bu sorunu ele alan MatPlotLib belgelerinde buldum: http://matplotlib.org/faq/howto_faq.html#generate-images-without-having-a-window-appear

Şeklin ortaya çıkmasını önlemenin en kolay yolunun etkileşimli olmayan bir arka uç (ör. Agg) matplotib.use(<backend>), örneğin:

import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
plt.plot([1,2,3])
plt.savefig('myfig')

Ben hala kişisel olarak kullanmayı tercih ediyorum plt.close( fig ), çünkü o zaman belirli rakamları (bir döngü sırasında) gizleme seçeneğiniz var, ancak yine de döngü sonrası veri işleme için rakamları görüntülüyorsunuz. Muhtemelen etkileşimli olmayan bir arka uç seçmekten daha yavaştır - birisi bunu test ederse ilginç olurdu.

GÜNCELLEME : Spyder için, genellikle arka ucu bu şekilde ayarlayamazsınız (Spyder genellikle matplotlib'i erken yükler, kullanmanızı engeller matplotlib.use()).

Bunun yerine, Spyder tercihlerinde plt.switch_backend('Agg')" etkinleştirmeyi etkinleştir " seçeneğini kullanın veya kapatın vematplotlib.use('Agg') komutu kendiniz .

Bu iki ipucundan: bir , iki


1
Bu, ayarlanmış bir ekranınızın olmadığı durumlarda gerçekten iyi çalışır. Doğru şekilde ayarlanmadıysa, başka bir arka ucun kullanılması .plot()hata verir os.environ['DISPLAY'].
ekonomi

1
Teşekkürler. Bu, internet bağlantısı olmayan ve herhangi bir paket yüklemek için sistem yöneticisine ihtiyaç duyduğu üretim sunucuları için çok yararlıdır.
Leon

Matplotlib sitesinin "backends" açıklaması / tanımı için olan öğreticiyi beğendim: matplotlib.org/tutorials/introductory/…
Tanner Strunk

47

"Mevcut" figür kavramını beğenmediyseniz, şunları yapın:

import matplotlib.image as mpimg

img = mpimg.imread("src.png")
mpimg.imsave("out.png", img)

2
Bu sadece kopyalamaz src.pngiçin out.png?
gerrit

Bu yalnızca bir örnek nesneniz ( img) olup olmadığını gösteren bir örnektir, .imsave()yöntemle dosyaya kaydedebilirsiniz .
wonder.mice

4
@ wonder.mice, geçerli şekli kullanmadan nasıl görüntü oluşturulacağını göstermeye yardımcı olur.
6'da scry

@ wonder.mice Bu örnek için teşekkürler, bana bir görüntü nesnesinin .png dosyasına nasıl kaydedileceğini gösteren ilk örnek.
Arthur Dent

@scry Her zaman bir görüntü oluşturmanıza gerek yoktur, bazen bazı kodlar dener ve görsel bir çıktı istersiniz, bu gibi durumlarda kullanışlıdır.
Schütze

29

Diğer cevaplar doğrudur. Ancak bazen şekil nesnesini daha sonra açmak istediğimi fark ediyorum . Örneğin, etiket boyutlarını değiştirmek, ızgara eklemek veya başka işlemler yapmak isteyebilirim. Mükemmel bir dünyada, basitçe arsa üreten kodu yeniden çalıştırır ve ayarları uyarlarım. Ne yazık ki, dünya mükemmel değil. Bu nedenle, PDF veya PNG'ye kaydetmenin yanı sıra şunu ekliyorum:

with open('some_file.pkl', "wb") as fp:
    pickle.dump(fig, fp, protocol=4)

Bunun gibi, daha sonra şekil nesnesini yükleyebilir ve ayarları istediğim gibi değiştirebilirim.

Ayrıca, yığıntaki locals()her işlev / yöntem için kaynak kodu ve sözlükle yığını yazarım , böylece daha sonra şekli tam olarak neyin ürettiğini söyleyebilirim.

Dikkat: Bazen bu yöntem çok büyük dosyalar oluşturduğundan dikkatli olun.


rakamlar yerinde iken, bir jupyter not defterinde geliştirme yapmak daha kolay olmaz mıydı? Bu şekilde geçmişi tam olarak izleyebilir ve hatta yeniden çalıştırabilirsiniz.
Ciprian Tomoiagă

3
@CiprianTomoiaga Hiçbir zaman etkileşimli bir Python kabuğundan (Jupyter veya başka bir şekilde) üretim grafikleri oluşturmam. Ben tüm senaryolardan arsa yazıyorum.
gerrit

28
import datetime
import numpy as np
from matplotlib.backends.backend_pdf import PdfPages
import matplotlib.pyplot as plt

# Create the PdfPages object to which we will save the pages:
# The with statement makes sure that the PdfPages object is closed properly at
# the end of the block, even if an Exception occurs.
with PdfPages('multipage_pdf.pdf') as pdf:
    plt.figure(figsize=(3, 3))
    plt.plot(range(7), [3, 1, 4, 1, 5, 9, 2], 'r-o')
    plt.title('Page One')
    pdf.savefig()  # saves the current figure into a pdf page
    plt.close()

    plt.rc('text', usetex=True)
    plt.figure(figsize=(8, 6))
    x = np.arange(0, 5, 0.1)
    plt.plot(x, np.sin(x), 'b-')
    plt.title('Page Two')
    pdf.savefig()
    plt.close()

    plt.rc('text', usetex=False)
    fig = plt.figure(figsize=(4, 5))
    plt.plot(x, x*x, 'ko')
    plt.title('Page Three')
    pdf.savefig(fig)  # or you can pass a Figure object to pdf.savefig
    plt.close()

    # We can also set the file's metadata via the PdfPages object:
    d = pdf.infodict()
    d['Title'] = 'Multipage PDF Example'
    d['Author'] = u'Jouni K. Sepp\xe4nen'
    d['Subject'] = 'How to create a multipage pdf file and set its metadata'
    d['Keywords'] = 'PdfPages multipage keywords author title subject'
    d['CreationDate'] = datetime.datetime(2009, 11, 13)
    d['ModDate'] = datetime.datetime.today()

28

İstediğiniz içeriği oluşturmak için plot () ve diğer işlevleri kullandıktan sonra, ekrana veya dosyaya çizim arasında seçim yapmak için aşağıdaki gibi bir cümle kullanabilirsiniz:

import matplotlib.pyplot as plt

fig = plt.figure(figsize=(4, 5))       # size in inches
# use plot(), etc. to create your plot.

# Pick one of the following lines to uncomment
# save_file = None
# save_file = os.path.join(your_directory, your_file_name)  

if save_file:
    plt.savefig(save_file)
    plt.close(fig)
else:
    plt.show()

Bazıları fig = plt.figure(figuresize=4, 5)olabilirfig = plt.figure(figsize=(4, 5)) #figure sizes in inches
kullanıcı

24

Aşağıdakileri kullandım:

import matplotlib.pyplot as plt

p1 = plt.plot(dates, temp, 'r-', label="Temperature (celsius)")  
p2 = plt.plot(dates, psal, 'b-', label="Salinity (psu)")  
plt.legend(loc='upper center', numpoints=1, bbox_to_anchor=(0.5, -0.05),        ncol=2, fancybox=True, shadow=True)

plt.savefig('data.png')  
plt.show()  
f.close()
plt.close()

Ben şekil kaydettikten sonra plt.how kullanmak için çok önemli buldum, aksi takdirde işe yaramaz. png olarak ihraç edilen rakam


2
üzgünüm, bunda ne var? çizilen görüntü dosyası? f= plt.savefig('data.png')
Mors

14

Bunlardan birini yapabilirsiniz:

plt.show(hold=False)
plt.savefig('name.pdf')

ve GUI grafiğini kapatmadan önce savefig dosyasının bitmesine izin vermeyi unutmayın. Bu şekilde görüntüyü önceden görebilirsiniz.

Alternatif olarak, birlikte bakabilirsin plt.show() Sonra yakın GUI ve komut dosyasını tekrar çalıştırın, ancak bu kez yerini plt.show()ile plt.savefig().

Alternatif olarak,

fig, ax = plt.figure(nrows=1, ncols=1)
plt.plot(...)
plt.show()
fig.savefig('out.pdf')

2
'hold' beklenmeyen bir anahtar kelime argümanı var
amitdatta

13

Benim gibi Spyder IDE kullanıyorsanız etkileşimli modu şu yöntemlerle devre dışı bırakmanız gerekir:

plt.ioff()

(bu komut bilimsel başlatma ile otomatik olarak başlatılır)

Tekrar etkinleştirmek istiyorsanız, şunu kullanın:

plt.ion()


12

Çözüm :

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import matplotlib
matplotlib.style.use('ggplot')
ts = pd.Series(np.random.randn(1000), index=pd.date_range('1/1/2000', periods=1000))
ts = ts.cumsum()
plt.figure()
ts.plot()
plt.savefig("foo.png", bbox_inches='tight')

Görüntüyü görüntülemek ve görüntü kullanımını kaydetmek istiyorsanız:

%matplotlib inline

sonra import matplotlib


9

Soruya göre Matplotlib (pyplot) savefig boş görüntü verir .

Bir şey not etmelisiniz: kullanırsanız plt.showve sonra kullanmanız gerekiyorsa plt.savefigveya boş bir görüntü vereceksiniz.

Ayrıntılı bir örnek:

import numpy as np
import matplotlib.pyplot as plt


def draw_result(lst_iter, lst_loss, lst_acc, title):
    plt.plot(lst_iter, lst_loss, '-b', label='loss')
    plt.plot(lst_iter, lst_acc, '-r', label='accuracy')

    plt.xlabel("n iteration")
    plt.legend(loc='upper left')
    plt.title(title)
    plt.savefig(title+".png")  # should before plt.show method

    plt.show()


def test_draw():
    lst_iter = range(100)
    lst_loss = [0.01 * i + 0.01 * i ** 2 for i in xrange(100)]
    # lst_loss = np.random.randn(1, 100).reshape((100, ))
    lst_acc = [0.01 * i - 0.01 * i ** 2 for i in xrange(100)]
    # lst_acc = np.random.randn(1, 100).reshape((100, ))
    draw_result(lst_iter, lst_loss, lst_acc, "sgd_method")


if __name__ == '__main__':
    test_draw()

resim açıklamasını buraya girin


6
import matplotlib.pyplot as plt
plt.savefig("image.png")

Jupyter Notebook'da , bir hücrede plt kodunun geri kalanıyla birlikte kaldırmanız plt.show()ve eklemeniz gerekir plt.savefig(). Görüntü yine de not defterinizde görünecektir.


1
"kaldır plt.show ()" .. bu günümü kurtardı ...
Guru

4

Bugün (bu soru yapıldığında mevcut değildi) birçok insanın Jupyter Notebook'u python konsolu olarak kullandığı göz önüne alındığında, grafikleri kaydetmek için son derece kolay bir yol var, .pngçünkü matplotlib's pylabsınıfını Jupyter Notebook'dan çağırın, rakamı yerinde çizin' 'jupyter hücreleri' ni tıklatın ve ardından bu şekli / resmi yerel bir dizine sürükleyin. %matplotlib inlineİlk satırda unutmayın !


1
Bu iyi bir fikir, sadece görüntü not defterine gömülü kalırsa dosya boyutu üzerindeki etkisini not almanız gerekir ..
prusswan

3

Buna ek olarak __file__, resim ve Python dosyası aynı adları almak için adı ekledim . Daha iyi görünmesi için birkaç argüman ekledim:

# Saves a PNG file of the current graph to the folder and updates it every time
# (nameOfimage, dpi=(sizeOfimage),Keeps_Labels_From_Disappearing)
plt.savefig(__file__+".png",dpi=(250), bbox_inches='tight')
# Hard coded name: './test.png'

2

Kullanırken matplotlib.pyplot, önce planınızı kaydetmeli ve ardından şu 2 satırı kullanarak kapatmalısınız:

fig.savefig('plot.png') # save the plot, place the path you want to save the figure in quotation
plt.close(fig) # close the figure window

1

Daha önce önerildiği gibi, aşağıdakilerden birini kullanabilirsiniz:

import matplotlib.pyplot as plt
plt.savefig("myfig.png")

Görüntülemekte olduğunuz IPhython görüntüsünü kaydetmek için. Veya farklı bir notta (farklı bir açıdan bakıldığında), açık cv ile çalışmaya başlarsanız veya açık cv ithal edildiyseniz, şunları yapabilirsiniz:

ithalat cv2

cv2.imwrite ( "myfig.png", görüntü)

Ancak bu, Açık CV ile çalışmanız gerektiğinde mümkündür. Aksi takdirde plt.savefig () yeterli olmalıdır.


0

Resminizi herhangi bir uzantıyla (png, jpg, vb.) Ve istediğiniz çözünürlükle kaydedebilirsiniz. İşte figürünüzü kaydetmek için bir fonksiyon.

import os

def save_fig(fig_id, tight_layout=True, fig_extension="png", resolution=300):
    path = os.path.join(IMAGES_PATH, fig_id + "." + fig_extension)
    print("Saving figure", fig_id)
    if tight_layout:
        plt.tight_layout()
    plt.savefig(path, format=fig_extension, dpi=resolution)

'fig_id' figürünüzü kaydetmek istediğiniz isimdir. Umarım yardımcı olur:)


0

Bunu şöyle yapabilirsiniz:

def plotAFig():
  plt.figure()
  plt.plot(x,y,'b-')
  plt.savefig("figurename.png")
  plt.close()
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.