在matplotlib中重绘图最终会导致python.exe崩溃

时间:2017-01-04 09:27:35

标签: python python-2.7 animation matplotlib leap-motion

我对matplotlib不熟悉所以请在解释时请耐心等待。

我正在使用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。更具体地说,Python 2.7.8(默认,2014年6月30日,16:03:49)[MSC v.1500 32 bit(英特尔)]在win32上。

2 个答案:

答案 0 :(得分: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 Device获得的新x和y值并将它们附加到坐标:

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

使用新坐标更新你的情节:

line.set_data(xs, ys)

答案 1 :(得分:-1)

def myfunc(x):         return 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')