【发布时间】:2017-05-28 13:07:32
【问题描述】:
我正在使用matplotlib 到interactively 绘制一些patches 和points。
我通过队列从单独的进程接收数据并将它们发送到我的绘图进程。这部分代码工作正常,点显示在图表上,并按预期在图表中不断更新。
根据用户的要求,我想删除情节中的所有旧补丁并替换为新补丁。
我认为表演就足够了:
# remove the old patch
patch.remove()
# I also tried ax.cla() without any success
# create a new patch
monitor_box = path.Path([(305, 500), (11, -213), (300, -220), (500, 1734)])
patch = patches.PathPatch(monitor_box, facecolor='black', lw=1)
# add the patch to the axis
ax.add_patch(patch)
然后在下一次迭代中,应该使用新补丁更新绘图:
canvas.draw()
但是当我使用上面的代码时,补丁仍然保留在窗口中,没有任何变化。 (我仍然在情节中获得积分,因此至少仍在不断更新)
下面我提供了该问题的最小工作示例。运行代码时,您可以看到绘制了不同的点,但补丁从未被删除。
import matplotlib
matplotlib.use('TkAgg')
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg
import multiprocessing
from Tkinter import *
import matplotlib.path as path
import matplotlib.patches as patches
import sys, thread, time
from random import randint
#Create a window
window=Tk()
sendProximityInfo = True
latest_published_msg = ""
def erasePatchesAndCreateNew_A():
print "erasePatchesAndCreateNew_A"
global line, ax, canvas
global monitor_box
global patch
patch.remove()
ax.cla()
monitor_box = path.Path([(35, 1677), (11, -213), (652, -220), (500, 1734)])
patch = patches.PathPatch(monitor_box, facecolor='black', lw=1)
ax.add_patch(patch)
def erasePatchesAndCreateNew_B():
print "erasePatchesAndCreateNew_B"
global line, ax, canvas
global monitor_box
global patch
patch.remove()
ax.cla()
monitor_box = path.Path([(35, 500), (11, -213), (300, -220), (500, 1734)])
patch = patches.PathPatch(monitor_box, facecolor='red', lw=1)
ax.add_patch(patch)
monitor_box = path.Path([(35, 1677), (111, -213), (62, -220), (800, 1734)])
fig = matplotlib.figure.Figure()
ax = fig.add_subplot(1,1,1)
ax.set_xlim(-1500,2000)
ax.set_ylim(-1500,2000)
patch = patches.PathPatch(monitor_box, facecolor='black', lw=1)
ax.add_patch(patch)
def main():
erasePatchesAndCreateNew_B()
#Create a queue to share data between process
q = multiprocessing.Queue()
#Create and start the simulation process
simulate = multiprocessing.Process(None, simulation,args=(q,))
simulate.start()
#Create the base plot
plot()
#Call a function to update the plot when there is new data
updateplot(q)
window.mainloop()
print 'Done'
simulate.join() # wait for the other process to finish as well
def plot(): #Function to create the base plot, make sure to make global the lines, axes, canvas and any part that you would want to update later
global line, ax, canvas
global monitor_box
global patch
fig = matplotlib.figure.Figure()
ax = fig.add_subplot(1,1,1)
ax.set_xlim(-1500,2000)
ax.set_ylim(-1500,2000)
patch = patches.PathPatch(monitor_box, facecolor='black', lw=1)
ax.add_patch(patch)
ax.invert_yaxis()
canvas = FigureCanvasTkAgg(fig, master=window)
canvas.show()
canvas.get_tk_widget().pack(side=TOP, fill=BOTH, expand=1)
canvas._tkcanvas.pack(side=TOP, fill=BOTH, expand=1)
line, = ax.plot([], [], 'ro')
def updateplot(q):
try: #Try to check if there is data in the queue
result = q.get_nowait()
if result != 'Q':
x, y = result
line.set_data(x, y)
ax.draw_artist(line)
canvas.draw()
window.after(1,updateplot,q)
else:
print 'done'
except:
window.after(1,updateplot,q)
def simulation(q):
try:
while True:
for i in range(10):
q.put( (randint(0,1500), randint(0,1500)) )
time.sleep(1)
erasePatchesAndCreateNew_A()
time.sleep(1)
for i in range(10):
q.put( (randint(0,1500), randint(0,1500)) )
time.sleep(1)
erasePatchesAndCreateNew_B()
time.sleep(1)
except KeyboardInterrupt:
print "received KeyboardInterrupt"
finally:
print "simulation ended"
sys.exit()
if __name__ == '__main__':
main()
【问题讨论】:
-
在
updateplot函数中没有对patch.remove()的调用。那么您到底希望发生什么? -
@ImportanceOfBeingErnest 我只是没有添加那部分代码,configureForPortrait() 和 configureForLandscape() 是从代码的其他地方调用的。
-
没有minimal reproducible example 几乎不可能找到问题所在。另一方面,创建这样的minimal reproducible example 并不难。在我看来,如果你懒得制作一个,为什么还要有人为你寻找解决方案。
-
@ImportanceOfBeingErnest 请查看编辑,我添加了一个最小的完整示例
标签: python-2.7 matplotlib tkinter