web-dev-qa-db-ja.com

matplotlibで図を個別に表示するにはどうすればよいですか?

Matplotlibに2つの図があり、図ごとに1つのプロットがあるとします。

import matplotlib.pyplot as plt

f1 = plt.figure()
plt.plot(range(0,10))
f2 = plt.figure()
plt.plot(range(10,20))

それから私は両方を一度に見せます

plt.show()

それらを個別に表示する方法、つまりf1だけを表示する方法はありますか?

または、より良い方法:管理以下の「希望的」コードのように、数字を個別に処理できます(動作しません)。

f1 = plt.figure()
f1.plot(range(0,10))
f1.show()
44

確かに。 add_subplotを使用してAxesを追加します。 (importを編集。)(showを編集。)

import matplotlib.pyplot as plt
f1 = plt.figure()
f2 = plt.figure()
ax1 = f1.add_subplot(111)
ax1.plot(range(0,10))
ax2 = f2.add_subplot(111)
ax2.plot(range(10,20))
plt.show()

または、add_axesを使用します。

ax1 = f1.add_axes([0.1,0.1,0.8,0.8])
ax1.plot(range(0,10))
ax2 = f2.add_axes([0.1,0.1,0.8,0.8])
ax2.plot(range(10,20))
39
Steve Tjoa

バージョン1.0.1より前のMatplotlibでは、特定の環境(一部のバックエンド、一部のプラットフォームなど)で動作するように見える場合でも、show()プログラムごとに1回だけ呼び出す必要があります )。

関連する描画関数は、実際にはdraw()です:

_import matplotlib.pyplot as plt

plt.plot(range(10))  # Creates the plot.  No need to save the current figure.
plt.draw()  # Draws, but does not block
raw_input()  # This shows the first figure "separately" (by waiting for "enter").

plt.figure()  # New window, if needed.  No need to save it, as pyplot uses the concept of current figure
plt.plot(range(10, 20))
plt.draw()
# raw_input()  # If you need to wait here too...

# (...)

# Only at the end of your program:
plt.show()  # blocks
_

show()は、さまざまな図(サイズ変更など)のイベントを処理するために設計された無限ループであることを認識することが重要です。原則として、スクリプトの先頭でdraw()を呼び出す場合、matplotlib.ion()への呼び出しはオプションです(ただし、一部のプラットフォームおよびバックエンドではこれが失敗します)。

Matplotlibが図を作成し、オプションでそれを表示するメカニズムを提供するとは思わない。これは、figure()で作成されたすべての図が表示されることを意味します。別々の図を連続して表示する必要がある場合(同じウィンドウに表示するかどうかにかかわらず)、上記のコードのようにできます。

さて、上記のソリューションは、単純な場合、およびいくつかのMatplotlibバックエンドで十分かもしれません。いくつかのバックエンドは、show()を呼び出していない場合でも、最初の図とやり取りできるほど十分に優れています。しかし、私が理解している限り、彼らはニースである必要はありません。最も堅牢なアプローチは、各図形描画を個別のスレッドで起動し、各スレッドに最後のshow()を追加することです。これは本質的に IPython が行うことだと思います。

ほとんどの場合、上記のコードで十分です。

[〜#〜] ps [〜#〜]:現在、Matplotlibバージョン1.0.1+では、show()を呼び出すことができます複数回(ほとんどのバックエンドで)。

25
Eric O Lebigot

私はパーティーに少し遅れていると思いますが...私の意見では、必要なのはmatplotlibのオブジェクト指向APIです。 matplotlib 1.4.2で、Qt4AggバックエンドでIPython 2.4.1を使用すると、次のことができます。

import matplotlib.pyplot as plt
fig, ax = plt.subplots(1) # Creates figure fig and add an axes, ax.
fig2, ax2 = plt.subplots(1) # Another figure

ax.plot(range(20)) #Add a straight line to the axes of the first figure.
ax2.plot(range(100)) #Add a straight line to the axes of the first figure.

fig.show() #Only shows figure 1 and removes it from the "current" stack.
fig2.show() #Only shows figure 2 and removes it from the "current" stack.
plt.show() #Does not show anything, because there is nothing in the "current" stack.
fig.show() # Shows figure 1 again. You can show it as many times as you want.

この場合、plt.show()は「現在の」スタック内のすべてを表示します。 GUIバックエンド(Qt4Aggなど)を使用している場合にのみ、figure.show()を指定できます。さもなければ、私はあなたが本当にソリューションを猿パッチするためにmatplotlibの内臓を掘り下げる必要があると思う。

ほとんどの(すべて?)plt。*関数は、FigureおよびAxesメソッドの単なるショートカットおよびエイリアスであることを覚えておいてください。これらはシーケンシャルプログラミングに非常に役立ちますが、より複雑な方法で使用する予定がある場合、すぐにブロックする壁を見つけるでしょう。

おそらく、 Matplotlibのインタラクティブな使用法 について読む必要があります。ただし、アプリをビルドする場合は、 [〜#〜] api [〜#〜] を使用し、選択したGUIツールキットのウィンドウに数字を埋め込む必要があります(examples/embedding_in_tk.pyなど)。

2

私の場合、_matplotlib 3.1.0_および_Python 3.7.3_を使用した場合、上記のソリューションはどれも動作しないようです。 show()を呼び出すと両方の図が表示されるか、上記のさまざまな回答に表示されません。

@Ivanの答えに基づいて、 here からヒントを得ると、次のことがうまく機能しているように見えました。

_import matplotlib.pyplot as plt
fig, ax = plt.subplots(1) # Creates figure fig and add an axes, ax.
fig2, ax2 = plt.subplots(1) # Another figure

ax.plot(range(20)) #Add a straight line to the axes of the first figure.
ax2.plot(range(100)) #Add a straight line to the axes of the first figure.

# plt.close(fig) # For not showing fig
plt.close(fig2) # For not showing fig2
plt.show()
_
1
arpanmangal