web-dev-qa-db-ja.com

Matplotlibを使って表示するのではなく、プロットを画像ファイルに保存する

私はその場でプロットを生成するための簡単なスクリプトを書いています。出発点として( Matplotlib documentationから)以下のコードを使用しています。

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

プロットをGUIで表示するのではなく、プロットをファイル(たとえばfoo.png)に保存して、たとえばバッチスクリプトで使用できるようにします。それ、どうやったら出来るの?

927

質問に答えましたが、 matplotlib.pyplot.savefig を使うときに役立つヒントをいくつか追加します。ファイルフォーマットは拡張子で指定できます。

from matplotlib import pyplot as plt

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

それぞれラスタライズまたはベクトル化された出力を提供します。どちらも便利です。さらに、pylabは寛大で、しばしば望ましくない、画像の周りの空白を残すことがわかります。それを削除します。

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

他の人が言っているように、plt.savefig()またはfig1.savefig()は確かに画像を保存する方法です。

しかし、特定のケース(Spyderがplt.ion():interactiveモード=オンの場合など)では、図が常に表示されることがわかりました。私は巨大なループの中でFigureウィンドウを強制的に閉じることでこれを回避しているので、ループの間に100万個のFigureを開くことはありません。

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
157
Demis

解決策は次のとおりです。

pylab.savefig('foo.png')
155

まさにこの問題を扱っているMatPlotLibドキュメンテーションのこのリンクを見つけてください: http://matplotlib.org/faq/howto_faq.html#generate-images-without-having-a-window-appear

彼らは、Figureがポップアップしないようにする最も簡単な方法は、matplotib.use(<backend>)を介して、非インタラクティブバックエンド(例:Agg)を使うことであると言います。

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

個人的にはplt.close( fig )を使うことを今でもお勧めします。それ以来、(ループ中に)特定の数字を隠すことができますが、それでもループ後のデータ処理のために数字を表示します。それはおそらく非対話的なバックエンドを選ぶより遅いでしょう - 誰かがそれをテストしたならば面白いでしょう。

_ update _ :Spyderの場合、通常この方法でバックエンドを設定することはできません(Spyderは通常matplotlibを早くロードするため、matplotlib.use()を使用できません)。

代わりにplt.switch_backend('Agg')を使うか、Spyderの設定で "サポートを有効にする"をオフにしてmatplotlib.use('Agg')コマンドを自分で実行してください。

これら2つのヒントから: onetwo

79
Demis

「現在」の図の概念が気に入らない場合は、次のようにします。

import matplotlib.image as mpimg

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

他の答えは正しいです。しかし、後で object という数字を開きたいと思うことがあります。たとえば、ラベルサイズを変更したり、グリッドを追加したり、その他の処理を実行したりできます。完璧な世界では、私は単にプロットを生成するコードを再実行し、そして設定を適応させるでしょう。ああ、世界は完璧ではありません。したがって、PDFまたはPNGに保存することに加えて、以下を追加します。

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

このように、後でfigureオブジェクトを読み込み、設定を操作することができます。

また、スタック内の各関数/メソッドについて、ソースコードとlocals()ディクショナリを使用してスタックを書き出します。これにより、後で何を生成したのかを正確に判断できます。

NB:時々この方法は巨大なファイルを生成するので注意してください。

26
gerrit
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()
24
Victor Juliet

Plot()と他の関数を使って必要なコンテンツを作成した後、次のような句を使って画面への印刷とファイルへの印刷を選択できます。

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()
23
Mark P.

私は以下を使いました:

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

Figureを保存した後にplt.showを使用することが非常に重要であることがわかりました、そうでなければそれは動作しません。 Figureはpngでエクスポートされます

21
Cristian Muñoz

どちらでもできます。

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

gUIプロットを閉じる前に、savefigを終了させることを忘れないでください。これにより、事前に画像を見ることができます。

あるいは、plt.show()でそれを見てからGUIを閉じてスクリプトを再度実行しますが、今度はplt.show()plt.savefig()に置き換えます。

あるいは、あなたは使うことができます

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

ソリューション :

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

画像を保存するだけでなく画像を表示したい場合は、次のようにします。

%matplotlib inline

import matplotlibの後

11
Durgesh satam

もし私と同じようにSpyder IDEを使っているのなら、インタラクティブモードを無効にする必要があります。

plt.ioff()

(このコマンドは科学的なスタートアップと共に自動的に起動されます)

もう一度有効にしたい場合は、次のようにします。

plt.ion()

11
Covich

質問によると Matplotlib(pyplot)savefigは空白の画像を出力します

注意すべき点が1つあります。plt.showを使用し、それがplt.savefigの後に使用する場合、または空白の画像を表示する場合.

詳細な例:

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 __== '__main__':
    test_draw()

enter image description here

6
Jayhello
#write the code for the plot     
plt.savefig("filename.png")

ファイルは、実行中のpython/Jupyterファイルと同じディレクトリに保存されます。

5
Swaraj Kumar
import matplotlib.pyplot as plt
plt.savefig("image.png")

Jupyter Notebookでは、plt.show()を削除し、plt.savefig()を1つのセルにpltコードの残りと共に追加する必要があります。それでも画像はノートブックに表示されます。

4
Punnerud

今日(この質問がなされたときには利用できませんでした)多くの人がJupyter NotebookをPythonコンソールとして使うので、プロットを.pngとして保存する非常に簡単な方法があります。ただmatplotlibpylabクラスJupyter NotebookからFigureの「インライン」jupyterセルをプロットし、そのfigure/imageをローカルディレクトリにドラッグします。 1行目に%matplotlib inlineを忘れないでください。

2
Hamidreza

上記に加えて、名前に__file__を追加して、写真とPythonファイルが同じ名前になるようにしました。また、見栄えを良くするためにいくつかの引数を追加しました。

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

最終的なヒントが見つかりました HERE

1
r_e

任意の拡張子(png、jpgなど)と希望する解像度で画像を保存できます。以下は、フィギュアを保存するための関数です。

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'は、フィギュアを保存する名前です。それが役に立てば幸い:)

0
Rudresh Dixit