2012-08-13 85 views
5

目標:繪製圖(x,y)並在圖w.r.t上將垂直線移動到計時器。Matplotlib圖中的進度線

我開始使用matplotlib來實現這個功能。它可能使用matplotlib的draw()特性來實現,但它會消耗CPU,因爲它每次都會重繪,並且不允許我與圖形進行交互。所以我決定使用matplotlib的動畫功能。在未來,我會喜歡暫停移動的線路。所以我不能使用matplotlib.animation.FuncAnimatin

問題:我使用canvas.copy_from_bbox(ax.bbox),ax.draw_artist(line),canvas.blit(ax.bbox)。 但是,我無法將圖形存儲在背景中並在其上移動一行。當我嘗試存儲時,它會以相當怪異的方式覆蓋。

這是我建立的代碼。任何人都可以幫我嗎?提前致謝。

import sys 
import matplotlib.pyplot as p 
import time 
fig=p.figure(); 
ax = fig.add_subplot(1,1,1) 

y=[];x=[];y1=[0,1000];x1=[0,0] 
y=numpy.random.randn(1000,1)*100 
x=numpy.arange(0,1000) 
line1, = ax.plot(x,y,color='black'); 
ax.set_ylim(0, 1000); 
line, = ax.plot(x1,y1,color='r',alpha=1,animated=True); # this is the line which i wanted to move over the graph w.r.t to time. (i can also use axvline , but i guess its the same). 
canvas = ax.figure.canvas 
canvas.draw() 
background = canvas.copy_from_bbox(ax.bbox); #my problem is here 
starttime=time.time(); 
mytimer=0; 
mytimer_ref=0; 
def update(canvas,line,ax): 
    canvas.restore_region(background) #my problem is here 
    t=time.time()-starttime; 
    mytimer=t+mytimer_ref; 
    x1=[mytimer,mytimer]; 
    line.set_xdata(x1); 
    ax.draw_artist(line) 
    canvas.blit(ax.bbox) #my problem is here 

def onclick(event): 
    global starttime 
    starttime=time.time(); 
    global mytimer_ref; 
    mytimer_ref=event.xdata; 
    print "starttime",starttime; 


cid=line1.figure.canvas.mpl_connect('button_press_event',onclick); # when i click the mouse over a point, line goes to that point and start moving from there. 
timer=fig.canvas.new_timer(interval=100); 
args=[canvas,line,ax]; 
timer.add_callback(update,*args); # every 100ms it calls update function 
timer.start(); 
p.show(); 
+0

什麼是 「相當不可思議的方式」 你指什麼? – pelson 2012-08-14 07:29:47

回答

4

因此,它看起來像「相當不可思議的方式」你指的是在本質上是錯誤的BBOX已抓獲與background = canvas.copy_from_bbox(ax.bbox)。我認爲這是大多數後端的已知問題,其中添加工具欄等會影響bbox的blitting位置。

本質上,如果您可以在之後捕獲背景窗口彈出,那麼一切都應該爲您工作。這可以通過多種方式完成,在您的情況下,最簡單的方法是用plt.show(block=False)替換canvas.draw()命令,該命令將調出窗口,而不會將其設置爲阻止命令。作爲一個輕微的補充,我相信你知道在python代碼中分號並不是必須的,但是當我調試的時候,我整理了一下你的代碼(沒有完成到底):

import sys 
import matplotlib.pyplot as plt 
import time 
import numpy 


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


max_height = 100 
n_pts = 100 
y1 = [0, max_height] 
x1 = [0, 0] 
y = numpy.random.randn(n_pts) * max_height 
x = numpy.arange(0, n_pts) 

# draw the data 
line1, = ax.plot(x, y, color='black') 

# fix the limits of the plot 
ax.set_ylim(0, max_height) 
ax.set_xlim(0, n_pts) 

# draw the plot so that we can capture the background and then use blitting 
plt.show(block=False) 

# get the canvas object 
canvas = ax.figure.canvas 
background = canvas.copy_from_bbox(ax.bbox) 

# add the progress line. 
# XXX consider using axvline 
line, = ax.plot(x1, y1, color='r', animated=True) 


starttime=time.time() 
mytimer=0 
mytimer_ref=0 

def update(canvas, line, ax): 
    # revert the canvas to the state before any progress line was drawn 
    canvas.restore_region(background) 

    # compute the distance that the progress line has made (based on running time) 
    t = time.time() - starttime 
    mytimer = t + mytimer_ref 
    x1 = [mytimer,mytimer] 
    # update the progress line with its new position 
    line.set_xdata(x1) 
    # draw the line, and blit the axes 
    ax.draw_artist(line) 
    canvas.blit(ax.bbox) 

def onclick(event): 
    global starttime 
    starttime=time.time() 
    global mytimer_ref 
    mytimer_ref=event.xdata 
    print "starttime",starttime 


cid=line1.figure.canvas.mpl_connect('button_press_event',onclick) # when i click the mouse over a point, line goes to that point and start moving from there. 
timer=fig.canvas.new_timer(interval=100) 
args=[canvas,line,ax] 
timer.add_callback(update,*args) # every 100ms it calls update function 
timer.start() 
plt.show() 

HTH

+0

嘿,非常感謝。它運作良好。但在2例中,它並不奏效。 1)當我們調整窗口大小和放大時。你有什麼建議嗎? – 2012-08-14 13:14:19

+0

我還猜測當我調整窗口大小和縮放窗口時,我應該可以添加一些事件來修改背景 – 2012-08-14 13:22:51

+0

您需要在調整大小時重新捕捉背景。我認爲這個活動是'resize_event'。我將通過「animate.py''的源代碼閱讀好例子(例如處理調整大小)。希望有幫助, – pelson 2012-08-14 15:45:13