2011-07-13 20 views
13

matplotlibに.png画像のシーケンスをプロットしたいと思います。目的は、ムービーの効果をシミュレートするためにそれらを素早くプロットすることですが、実際に.aviファイルを作成したり、matplotlibの数値を保存してPython以外の順番でそれらを表示しないようにしたいというさらなる理由があります。matplotlibプロットの時間順シーケンスをアニメーション化する方法

私は特に、画像ファイルをPythonのforループ内で順番に表示しようとしています。 matplotlibを正しくインポートしたと仮定して、自分の関数 'new_image()'と 'new_rect()'を持っています。show()関数のGUIメインループへの呼び出しをブロックする効果があるため、

for index in index_list: 
    img = new_image(index) 
    rect = new_rect(index) 

    plt.imshow(img) 
    plt.gca().add_patch(rect) 
    plt.show() 

    #I also tried pausing briefly and then closing, but this doesn't 
    #get executed due to the GUI mainloop from show() 
    time.sleep(0.25) 
    plt.close() 

上記のコードは最初の画像を表示するように動作しますが、その後、プログラムはちょうどハング、私は手動で結果figureウィンドウを閉じるために待ちます。私がそれを閉じると、プログラムはちょうどハングアップし、新しい画像データで再プロットしません。私は何をしなければならないのですか?また、plt.show()コマンドをplt.draw()コマンドで置き換えてから、forループの外にplt.show()を追加しようとしました。これは何も表示せず、ハングアップします。 http://matplotlib.sourceforge.net/examples/animation/simple_anim_tkagg.htmlに基づい

+0

私はmatplotlibのは本当にこれを念頭において設計されていない疑いがあります。しかし、いずれにしても、matplotlib特有のメーリングリストでこれについて質問するより多くの情報を得る可能性があります。 –

答えて

5

私はこのために見つけた最良の方法は、あなたがpylabをインポートした後、コマンドpylab.ion()していました。

show()を使用するスクリプトですが、pylab.draw()が呼び出されるたびに異なるプロットが表示され、プロットウィンドウが無期限に表示されます。単純な入力ロジックを使用して数字を閉じるタイミングを決定します(show()を使用すると、pylabはウィンドウxボタンのクリックを処理しません)ので、別のボタンまたはテキストフィールドとしてguiに追加するのは簡単です。

import numpy as np 
import pylab 
pylab.ion() 

def get_fig(fig_num, some_data, some_labels): 

    fig = pylab.figure(fig_num,figsize=(8,8),frameon=False) 
    ax = fig.add_subplot(111) 
    ax.set_ylim([0.1,0.8]); ax.set_xlim([0.1, 0.8]); 
    ax.set_title("Quarterly Stapler Thefts") 
    ax.pie(some_data, labels=some_labels, autopct='%1.1f%%', shadow=True); 
    return fig 

my_labels = ("You", "Me", "Some guy", "Bob") 

# To ensure first plot is always made. 
do_plot = 1; num_plots = 0; 

while do_plot: 
    num_plots = num_plots + 1; 
    data = np.random.rand(1,4).tolist()[0] 

    fig = get_fig(num_plots,data,my_labels) 
    fig.canvas.draw() 
    pylab.draw() 

    print "Close any of the previous plots? If yes, enter its number, otherwise enter 0..." 
    close_plot = raw_input() 

    if int(close_plot) > 0: 
     pylab.close(int(close_plot)) 

    print "Create another random plot? 1 for yes; 0 for no." 
    do_plot = raw_input(); 

    # Don't allow plots to go over 10. 
    if num_plots > 10: 
     do_plot = 0 

pylab.show() 

ここで基本的なロジックを変更することによって、私は映画の再生をシミュレートするために、連続してそれに近い窓やプロットイメージを持つことができ、または私はそれが映画を通じて、手順どのようにオーバーキーボード制御を維持することができます。

注:これはプラットフォーム間で私のために働いたと上のウィンドウのキャンバスマネージャのアプローチに厳密に優れているようだ、と「TkAgg」オプションを必要としませんしました。

8

import time 
import numpy as np 
import matplotlib 
matplotlib.use('TkAgg') # do this before importing pylab 

import matplotlib.pyplot as plt 
fig = plt.figure() 
ax = fig.add_subplot(111) 

def animate(): 
    tstart = time.time()     # for profiling 
    data=np.random.randn(10,10) 
    im=plt.imshow(data) 

    for i in np.arange(1,200): 
     data=np.random.randn(10,10) 
     im.set_data(data) 
     fig.canvas.draw()       # redraw the canvas 
    print 'FPS:' , 200/(time.time()-tstart) 

win = fig.canvas.manager.window 
fig.canvas.manager.window.after(100, animate) 
plt.show() 

plt.imshow

はfloat配列、UINT8アレイ、またはPIL画像を受け入れることができます。 あなたはPNGファイルのディレクトリを持っているような場合は、PILイメージとしてそれらを開いて、このようにそれらをアニメーション化できます。

import matplotlib 
matplotlib.use('TkAgg') # do this before importing pylab 
import matplotlib.pyplot as plt 
import Image 
import glob 

fig = plt.figure() 
ax = fig.add_subplot(111) 

def animate(): 
    filenames=sorted(glob.glob('*.png')) 
    im=plt.imshow(Image.open(filenames[0])) 
    for filename in filenames[1:]: 
     image=Image.open(filename) 
     im.set_data(image) 
     fig.canvas.draw() 

win = fig.canvas.manager.window 
fig.canvas.manager.window.after(100, animate) 
plt.show() 
+0

ランダムなプロットデータを実際のカラーPNG画像に置き換えると、これは機能しません。これは私が最初に試したことの一つです。 – ely

+0

それは私のために働いた、ちょうど最初に関数呼び出しを追加する必要があります: plt。 – MZHm

+1

@MZHm:コードの実行方法について詳しく教えてください。コマンドラインやIDEから? MatplotlibのどのOSとバージョンですか? AFAIK、上記のコードは、コマンドラインから実行されたときに 'plti.ion'なしで広告されたように動くべきです。 'plt.ion'はここでうまくいきますが、' plt.ion'を避けると、いつ物事が表示されるかをより詳細に制御できます。 – unutbu

0

私はあなたの必要性に合った便利なスクリプトを実装しました。以下はhere

それを試してみて、一緒にそのバウンディングボックスで画像を表示する例です。

import os 
import glob 
from scipy.misc import imread 
from matplotlib.pyplot import Rectangle 

video_dir = 'YOUR-VIDEO-DIRECTORY' 

img_files = glob.glob(os.path.join(video_dir, '*.jpg')) 
box_files = glob.glob(os.path.join(video_dir, '*.txt')) 

def redraw_fn(f, axes): 
    img = imread(img_files[f]) 
    box = bbread(box_files[f]) # Define your own bounding box reading utility 
    x, y, w, h = box 
    if not redraw_fn.initialized: 
     im = axes.imshow(img, animated=True) 
     bb = Rectangle((x, y), w, h, 
         fill=False, # remove background 
         edgecolor="red") 
     axes.add_patch(bb) 
     redraw_fn.im = im 
     redraw_fn.bb = bb 
     redraw_fn.initialized = True 
    else: 
     redraw_fn.im.set_array(img) 
     redraw_fn.bb.set_xy((x, y)) 
     redraw_fn.bb.set_width(w) 
     redraw_fn.bb.set_height(h) 
redraw_fn.initialized = False 

videofig(len(img_files), redraw_fn, play_fps=30) 
関連する問題