13

私は、matplotlib とスレッド化についてかなりの質問があることを知っています。また、pyplot はスレッドセーブではないことも知っています。ただし、この特定の問題については何も見つかりませんでした。私がやりたいことは、図をプロットして毎秒更新することです。このためにスレッドを作成したかったのですが、これまでのところ、スレッドから実際のプロットを取得することさえできませんでした. また、私は qt4 で立ち往生しているため、他のバックエンドの動作が異なる可能性があります。

非常に簡単な例を次に示します。プロットは で作成されplot_a_graph()ます。これは、メイン プログラムから呼び出された場合は正常に機能しますが、メイン コードの以降の実行を遅らせます。ただし、スレッドから呼び出された場合、グラフは表示されません。

import matplotlib
matplotlib.use("qt4agg")
import matplotlib.pyplot as plt
import threading
import time

def plot_a_graph():
    f,a = plt.subplots(1)
    line = plt.plot(range(10))
    plt.show()
    print "plotted graph"    
    time.sleep(4)


testthread = threading.Thread(target=plot_a_graph)

plot_a_graph()      # this works fine, displays the graph and waits
print "that took some time"

testthread.start() # Thread starts, window is opened but no graph appears
print "already there"

Thx ヘルプ

4

2 に答える 2

10

ここでの私の提案は、threading モジュールの代わりにpython multiprocessingモジュールを使用することです。サンプル コードにわずかな変更を加えるだけで、メイン プロセスの制御フローが続行されている間に、matplotlib プロットを子プロセスに正常にオフロードできました (以下のコードを参照)。

より大きなコード制御フローのコンテキストで子プロセスが親とやり取りするようにしたい場合は、マルチプロセッシングのドキュメント、またはこの件に関する多数のブログ投稿を読むことをお勧めしますあなたの質問で完全に説明されています)。マルチプロセッシングには、Python のグローバル インタープリター ロックを回避し、マルチコア コンピューター アーキテクチャを活用できるという追加の利点があることに注意してください。

#a slight modification of your code using multiprocessing
import matplotlib
matplotlib.use("qt4agg")
import matplotlib.pyplot as plt 
#import threading
#let's try using multiprocessing instead of threading module:
import multiprocessing
import time

#we'll keep the same plotting function, except for one change--I'm going to use the multiprocessing module to report the plotting of the graph from the child process (on another core):
def plot_a_graph():
    f,a = plt.subplots(1)
    line = plt.plot(range(10))
    print multiprocessing.current_process().name,"starting plot show process" #print statement preceded by true process name
    plt.show() #I think the code in the child will stop here until the graph is closed
    print multiprocessing.current_process().name,"plotted graph" #print statement preceded by true process name
    time.sleep(4)

#use the multiprocessing module to perform the plotting activity in another process (i.e., on another core):
job_for_another_core = multiprocessing.Process(target=plot_a_graph,args=())
job_for_another_core.start()

#the follow print statement will also be modified to demonstrate that it comes from the parent process, and should happen without substantial delay as another process performs the plotting operation:
print multiprocessing.current_process().name, "The main process is continuing while another process deals with plotting."
于 2013-10-31T23:45:33.253 に答える