我正在编写一个将曲线拟合到大型xy坐标数据集的程序。通过绘制和显示每次迭代的拟合过程,通常有助于观察算法的进展。我正在使用matplotlib来绘制。
我想做的是在主线程中创建图形,然后将其传递给显示它的子线程。这样我就可以在主线程中访问所有图形的方法和属性。我可以通过调用fig.gca().plot()来绘图,通过调用fig.canvas.draw()来绘图。
我不知道如何创建一个交互式绘图窗口,只显示我传递给它的图形。现在我正在使用matplotlib.pyplot.show(),它确实显示了我的图形,但它也显示了程序中可能定义的任何其他图形。是否有一种面向对象的方法来为特定的图形创建一个交互式窗口?我正在寻找一个不依赖于matplotlib中不支持的接口的解决方案。
这是一个类似的帖子,但它仍然没有回答我的问题:交互式图形与OO Matplotlib
我一直不明白为什么matplotlib似乎总是使用当前对象(当前图形,当前轴等)而不是特定对象(例如,为什么不使用matplotlib.pyplot.show(图)而不仅仅是show()?)我想我漏掉了什么。如果有人能告诉我为什么matplotlib是这样设计的,或者我是如何误解和/或滥用它的,那也将是感激的。
下面是我的代码:
import matplotlib.pyplot
import threading
import time
class Plotter():
def __init__(self,fig):
t = threading.Thread(target=self.PlottingThread,args=(fig,))
t.start()
def PlottingThread(self,fig):
#This line shows fig1 AND fig2 from below. I want it to show fig ONLY.
matplotlib.pyplot.show()
if __name__ == "__main__":
fig1 = matplotlib.pyplot.figure()
fig2 = matplotlib.pyplot.figure()
Plotter(fig1)
fig1.gca().clear()
fig1.gca().plot([1,2,3])
fig1.canvas.draw()
我想我明白了:
import Tkinter
import threading
import matplotlib.backends.backend_tkagg
root = Tkinter.Tk()
class Plotter():
def __init__(self,fig):
t = threading.Thread(target=self.PlottingThread,args=(fig,))
t.start()
def PlottingThread(self,fig):
canvas = matplotlib.backends.backend_tkagg.FigureCanvasTkAgg(fig, master=root)
canvas.show()
canvas.get_tk_widget().pack(side=Tkinter.TOP, fill=Tkinter.BOTH, expand=1)
toolbar = matplotlib.backends.backend_tkagg.NavigationToolbar2TkAgg(canvas, root)
toolbar.update()
canvas._tkcanvas.pack(side=Tkinter.TOP, fill=Tkinter.BOTH, expand=1)
Tkinter.mainloop()
if __name__ == "__main__":
import time
fig1 = matplotlib.figure.Figure(figsize=(5,4), dpi=100)
fig1.gca().plot([1,2,3])
fig2 = matplotlib.figure.Figure(figsize=(5,4), dpi=100)
fig2.gca().plot([3,2,1])
#Shows fig1 and not fig2, just like it's supposed to
Plotter(fig1)
time.sleep(1)
#I can still plot to fig1 from my main thread
fig1.gca().clear()
fig1.gca().plot([5,2,7])
fig1.canvas.draw()
唯一的问题是,如果您尝试创建两个Plotter实例,整个程序将崩溃。这对我的应用程序来说不是很重要,但这可能意味着我错误地使用了Tkinter。欢迎提出建议或更正