我有一个小程序,用4个子图绘制一个数字。我做一个小GUI并从一个线程调用该绘图函数,所以每次单击该按钮时,它应该重新收集数据并重绘该图(带有4个子图),而不关闭脚本。该脚本可以首次绘制,但是在第二次(单击按钮而不关闭脚本)时,它会在初始化子图时停止。我试过plt.close('all'),plt.close(图),plt.clf(),......但它没有用。我真的不知道为什么它会在第二次停止。
这是我的完整小脚本。非常感谢任何输入
import sys, os
import time
import wx
import traceback
from textwrap import wrap
import shutil
import itertools
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
import threading
def test():
Do = Data()
Do.PlotGraph()
class Data(object):
def __init__(self):
self.SavePath = "C:\\Plots\\"
def f(self, t):
return np.exp(-t) * np.cos(2*np.pi*t)
def PlotGraph(self):
#Plotting
print "***** Generating plot"
t1 = np.arange(0.0, 5.0, 0.1)
t2 = np.arange(0.0, 5.0, 0.02)
print "Initialize subplots"
fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(nrows = 2, ncols = 2, frameon=False, figsize=(20, 10))
fontSize = 13
print "Creating ax1"
ax1title = "ax1"
ax1.set_title(ax1title, fontsize = fontSize)
ax1.plot(t1, self.f(t1), 'bo', t2, self.f(t2), 'k')
print "Creating ax2"
ax2title = "ax2"
ax2.set_title(ax2title, fontsize = fontSize)
ax2.plot(t1, self.f(t1), 'bo', t2, self.f(t2), 'k')
print "Creating ax3"
ax3title = "ax3"
ax3.set_title(ax3title, fontsize = fontSize)
ax3.plot(t1, self.f(t1), 'bo', t2, self.f(t2), 'k')
print "Creating ax4"
ax4title = "ax4"
ax4.set_title(ax4title, fontsize = fontSize)
ax4.plot(t1, self.f(t1), 'bo', t2, self.f(t2), 'k')
fig.subplots_adjust(hspace = 0.35) #make room for axes title and x-axis label
fig.subplots_adjust(bottom = 0.07) #make room for axes title and x-axis label
fig.subplots_adjust(wspace = 0.30)
fig.subplots_adjust(top = .86)
filename= "Test"
if not os.path.exists(self.SavePath):
os.makedirs(self.SavePath)
savefilename = self.unique_file(self.SavePath, filename, "png")
print "***** Saving plot to: " + self.SavePath + savefilename
fig.savefig(self.SavePath + savefilename, dpi = 200)
plt.close(fig)
def unique_file(self, path, basename, ext):
actualname = "%s.%s" % (basename, ext)
c = itertools.count()
while os.path.exists(path + actualname):
actualname = "%s_[%d].%s" % (basename, next(c), ext)
#print "actualname: " + actualname
return actualname
################## THREAD UPDATE GUI ######################
#1. Create new custom event to update the display
DisplayEventType = wx.NewEventType();
EVT_DISPLAY = wx.PyEventBinder(DisplayEventType, 1);
def GetDataThreadStart(window):
GetDataThread(window)
class GetDataThread(threading.Thread):
def __init__(self, output_window):
threading.Thread.__init__(self)
self.output_window = output_window
print "Thread started"
self.start()
def run(self):
test()
print "Test Done\n\n"
self.UpdateFunction("Enable Go Button")
def UpdateFunction(self, msg):
evt = UpdateDisplayEvent(DisplayEventType, -1) #initialize update display event
evt.UpdateText(str(msg)); #update display event
wx.PostEvent(self.output_window, evt)
#Define event
class UpdateDisplayEvent(wx.PyCommandEvent):
def __init__(self, evtType, id):
wx.PyCommandEvent.__init__(self, evtType, id)
self.msg = ""
def UpdateText(self,text):
self.msg = text
def GetText(self):
return self.msg
######## Define GUI ###########
class MyPanel(wx.Panel):
def __init__(self, parent):
wx.Panel.__init__(self, parent, -1)
class MyFrame(wx.Frame):
def __init__(self, parent):
self.title = 'Testing'
wx.Frame.__init__(self, parent, -1, self.title, size = (300,350))
pnl = MyPanel(self)
self.Go_Button = wx.Button(pnl, -1, "Goooooo!")
self.Bind(wx.EVT_BUTTON, self.ClickGo, self.Go_Button)
BoxSizerMain = wx.BoxSizer(wx.VERTICAL)
BoxSizerMain.Add(self.Go_Button, 0, wx.ALIGN_CENTER_HORIZONTAL)
self.Bind(EVT_DISPLAY, self.OnThreadUpdate)
def ClickGo(self, event):
self.Go_Button.Disable()
GetDataThreadStart(self)
def OnThreadUpdate(self, event):
msg = event.GetText()
if msg == "Enable Go Button":
self.Go_Button.Enable()
def invokeGUI():
app = wx.PySimpleApp()
frame = MyFrame(None)
frame.Show()
frame.Iconize(True)
frame.Iconize(False)
frame.CenterOnScreen()
app.MainLoop()
if __name__ == '__main__':
invokeGUI()
结果
答案 0 :(得分:1)
我相信您需要通过matplotlib.use()
函数将matplotlib后端更改为wx,以便在wx图形中嵌入matplotlib图。
以下是我在剧本中更改的内容:
import matplotlib
matplotlib.use('WX')
import matplotlib.pyplot as plt
测试后产生了以下图像:
控制台输出:
Initialize subplots
Creating ax1
Creating ax2
Creating ax3
Creating ax4
***** Saving plot to: /Users/luccary/Downloads/foo/Test_[0].png
/Users/luccary/.virtualenvs/numpy/lib/python2.7/site-packages/matplotlib/cbook.py:136: MatplotlibDeprecationWarning: The WX backend is deprecated. It's untested and will be removed in Matplotlib 2.2. Use the WXAgg backend instead. See Matplotlib usage FAQ for more info on backends.
warnings.warn(message, mplDeprecation, stacklevel=1)
Test Done
请注意弃用警告,因为wx将在Matplotlib 2.2中作为后端删除,您应该使用wxagg。
参考文献:在阅读类似问题this matplotlib tutorial的Stack Overflow回答后,查看我发现的here。
希望能回答你的问题。祝你好运!