2017-01-04 55 views
0

我對matplotlib非常陌生,所以請在我解釋的時候耐心等待。在matplotlib中重繪圖最終崩潰python.exe

我正在使用matplotlib繪製其中有一些形狀的2D圖形。你可以看到下面的代碼和輸出圖:

from random import randint 
import matplotlib.path as path 
import matplotlib.pyplot as plt 
import matplotlib.patches as patches 

from matplotlib.pyplot import plot, ion, show 
import numpy 


box_a_midd_x = 200 
box_a_midd_y = -300 
box_a_width = 100 
box_a_height = 400 
box_a_x = box_a_midd_x - box_a_width/2 
box_a_y = box_a_midd_y - box_a_height/2 
box_a = path.Path([(box_a_x, box_a_y), (box_a_x, box_a_y + box_a_height), (box_a_x + box_a_height, box_a_y + box_a_height), (box_a_x + box_a_height, box_a_y)]) 

box_b_midd_x = 700 
box_b_midd_y = 100 
box_b_width = 200 
box_b_height = 400 
box_b_x = box_b_midd_x - box_b_width/2 
box_b_y = box_b_midd_y - box_b_height/2 
box_b = path.Path([(box_b_x, box_b_y), (box_b_x, box_b_y + box_b_height), (box_b_x + box_b_height, box_b_y + box_b_height), (box_b_x + box_b_height, box_b_y)]) 

box_c_midd_x = 700 
box_c_midd_y = 700 
box_c_width = 200 
box_c_height = 400 
box_c_x = box_c_midd_x - box_c_width/2 
box_c_y = box_c_midd_y - box_c_height/2 
box_c = path.Path([(box_c_x, box_c_y), (box_c_x, box_c_y + box_c_height), (box_c_x + box_c_height, box_c_y + box_c_height), (box_c_x + box_c_height, box_c_y)])  

box_d_midd_x = 700 
box_d_midd_y = 1400 
box_d_width = 200 
box_d_height = 400 
box_d_x = box_d_midd_x - box_d_width/2 
box_d_y = box_d_midd_y - box_d_height/2 
box_d = path.Path([(box_d_x, box_d_y), (box_d_x, box_d_y + box_d_height), (box_d_x + box_d_height, box_d_y + box_d_height), (box_d_x + box_d_height, box_d_y)])  

monitor_box = path.Path([(35, 1677), (11, -213), (652, -220), (500, 1734)]) 

print "A: " + str(box_a) 
print "B: " + str(box_b) 
print "C: " + str(box_c) 
print "D: " + str(box_d) 

#plt.plot([], []) 
#ion() 
fig = plt.figure() 
ax = fig.add_subplot(111) 
patch = patches.PathPatch(monitor_box, facecolor='black', lw=1) 
patch_a = patches.PathPatch(box_a, facecolor='orange', lw=2) 
patch_b = patches.PathPatch(box_b, facecolor='orange', lw=2) 
patch_c = patches.PathPatch(box_c, facecolor='orange', lw=2) 
patch_d = patches.PathPatch(box_d, facecolor='orange', lw=2) 
ax.add_patch(patch) 
ax.add_patch(patch_a) 
ax.add_patch(patch_b) 
ax.add_patch(patch_c) 
ax.add_patch(patch_d) 
ax.set_xlim(-2000,2000) 
ax.set_ylim(-2000,2000) 
plt.gca().invert_yaxis() 
#plt.plot([1], [1], 'ro') 
#plt.draw() 
#plt.show(block=False) 
#plt.show() 
plt.ion() 
xs = [0] 
ys = [0] 
line, = plt.plot([xs[0], ys[0]], 'ro') 
line.set_data(xs, ys) 
plt.show() 
plt.draw() 
plt.pause(0.001) 


def update_line(hl, new_data): 
    hl.set_xdata(numpy.append(hl.get_xdata(), new_data)) 
    hl.set_ydata(numpy.append(hl.get_ydata(), new_data)) 
    plt.draw() 



while(True): 
    app_x = randint(0,2000) 
    app_y = randint(0,2000) 

    isInsideA = box_a.contains_points([(app_x,app_y)]) 
    isInsideB = box_b.contains_points([(app_x,app_y)]) 
    isInsideC = box_c.contains_points([(app_x,app_y)]) 
    isInsideD = box_d.contains_points([(app_x,app_y)]) 
    whichBox = "" 
    if isInsideA: 
     whichBox = "A" 
    elif isInsideB: 
     whichBox = "B" 
    elif isInsideC: 
     whichBox = "C" 
    elif isInsideD: 
     whichBox = "D" 
    else: 
     whichBox = "..." 

    print ("X: " + str(int(app_x)) + "\t Y: " + str(int(app_y)) + " \t" + str(whichBox)) 
    xs[0] = int(app_x) 
    ys[0] = int(app_y) 
    line.set_data(xs, ys) 
    plt.show() 
    plt.draw() 

輸出圖像看起來像這樣(真的沒什麼奇怪的)。 graph

的問題是,幾秒鐘後,圖崩潰(Not responsing)(30-40秒,這似乎是隨機的)。 當圖形窗口掛起時,仍然可以看到python代碼仍在運行,並且打印了新值,但圖形中不再有任何反應。 我不知道在哪裏可以繼續。 請運行上面的完整小例子,並希望看到該問題。

我在Windows 7機器上運行Python 2.7.8。更具體地說,在Win32上的Python 2.7.8(默認,2014年6月30日,16:03:49)[MSC v.1500 32位(Intel)]。

+0

此線程似乎包含了一些有前途的方法。 http://stackoverflow.com/questions/10944621/dynamically-updating-plot-in-matplotlib – Henning

回答

-1

高清MYFUNC(X): 回報hasattr(X, 'SET_COLOR')

for o in fig.findobj(myfunc): 
    o.set_color('blue') 

import matplotlib.text as text 

for o in fig.findobj(text.Text): 
    o.set_fontstyle('italic') 
0

您創建的每個迭代一個新的陰謀。 更好地利用set_data()並追加到列表x上的y座標:

plt.ion() 
xs = [random.randint(-1000, 1000)] 
ys = [random.randint(-1000, 1000)] 
line, = plt.plot([xs[0], ys[0]], 'ro') 
for _ in range(1000): 
    xs.append(random.randint(-1000, 1000)) 
    ys.append(random.randint(-1000, 1000)) 
    line.set_data(xs, ys) 
    plt.show() 
    plt.draw() 
    plt.pause(0.001) 
plt.ioff() 
plt.show() 

這是兩個將與每一個隨機數:

xs = [random.randint(-1000, 1000)] 
ys = [random.randint(-1000, 1000)] 

現在,創建一個情節,使用這些列表:

line, = plt.plot([xs[0], ys[0]], 'ro') 

在循環中,模擬從LeapMotion設備獲得的新x和y值並將它們附加到您的座標:

xs.append(random.randint(-1000, 1000)) 
ys.append(random.randint(-1000, 1000)) 

更新您的劇情與新座標:

line.set_data(xs, ys) 
+0

我將你的建議合併到我的代碼中(區別在於我的代碼幾乎永遠在for循環中,並繼續繪製最新點)。 1分鐘左右後,圖表仍然掛起(不響應)。有任何想法嗎? – theAlse

+0

您需要用您的邏輯替換for循環以獲取新的x和y值。每次執行'line.set_data(xs,ys)'和**將不同的x和y追加到'xs'和'ys'時,您應該在不同的地方看到點。循環結束後,'plt.ioff()'停止動畫。在範圍(1000)中增加'for __範圍('):'爲範圍內的_(100000):'爲更長的動畫。 –

+0

我一次只顯示一個點,像這樣'self.xs [0] = int(app_x) self.ys [0] = int(app_y) self.line.set_data(self.xs,self。 ys)',仍然會在一段時間後崩潰圖形 – theAlse