Hello, I want to create a dynamic image with python. There are three panels in the frame, title panel, image panel, and information panel. The image changes dynamically in the image panel. I use the OnTimer to update the image. There are two OnTimer, one in image panel, and the other in main frame. The OnTimer() in main frame will call the OnTimer() in image panel. But question arises, it the value in timer.Start() is small, sometimes the top panel and information panel disappear. The combobox is disabled. And also the image flashes a lot. Could anyone help to fix it? Thanks a lot.
import wx
import sys, time, os, gc
import wx.lib.colourselect as cs
import matplotlib.cm as cm
import numpy as npy
import matplotlib.pyplot as plt
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg
from matplotlib.figure import Figure
TIMER_ID = wx.NewId()
# Class TopPanel creates a Text display
class TopPanel(wx.Panel):
def __init__(self, parent):
wx.Panel.__init__(self, parent)
font = wx.Font(20, wx.NORMAL, wx.NORMAL, wx.BOLD)
self.st = wx.StaticText(self, -1, "Pseudo Image", (5,10), style=wx.ALIGN_CENTRE)
self.st.SetFont(font)
self.SetForegroundColour((164, 211, 238)) # lightskyblue2
# Class PlotPanel creates a Image display and intensity distribution
class PlotPanel(wx.Panel):
def __init__( self, parent, cmap=cm.jet, dpi=None, xpix=800, ypix=600, **kwargs):
# initialize Panel
if 'id' not in kwargs.keys():
kwargs['id'] = wx.ID_ANY
if 'style' not in kwargs.keys():
kwargs['style'] = wx.NO_FULL_REPAINT_ON_RESIZE
wx.Panel.__init__( self, parent, **kwargs )
# initialize matplotlib stuff
self.figure = Figure((10,8), 80)
self.canvas = FigureCanvasWxAgg( self, -1, self.figure )
rect = [0.065,0.065,0.85,0.85]
self.ax = self.figure.add_axes(rect)
self.ax.xlim = ypix
self.ax.ylim = xpix
self.ax.set_xlim([0, self.ax.xlim])
self.ax.set_ylim([self.ax.ylim, 0])
self.cmap = cmap
self.Bind(wx.EVT_TIMER, self.OnTimer)
def InitPlot(self):
self.x = npy.empty((self.ax.xlim,self.ax.ylim))
self.x.flat = npy.arange(self.ax.ylim)*2*npy.pi/float(self.ax.ylim)
self.y = npy.empty((self.ax.ylim,self.ax.xlim))
self.y.flat = npy.arange(self.ax.xlim)*2*npy.pi*5.0/(self.ax.xlim*4.0)
self.y = npy.transpose(self.y)
z = npy.fabs(npy.sin(self.x)/2. + npy.cos(self.y)/2.)
self.im = self.ax.imshow( z, cmap=self.cmap)#, interpolation='nearest')
self.im.set_array(z)
self.canvas.draw()
def OnTimer(self, evt):
self.x += npy.pi/15
self.y += npy.pi/20
z = npy.fabs(npy.sin(self.x) + npy.cos(self.y))
self.im.set_array(z)
# self.onEraseBackground(evt)
self.canvas.draw()
class InfoPanel(wx.Panel):
def __init__(self, parent):
wx.Panel.__init__(self, parent)
font = wx.Font(20, wx.NORMAL, wx.NORMAL, wx.BOLD)
vbox = wx.BoxSizer(wx.VERTICAL)
xlabel = wx.StaticText(self, -1, 'X Pixels:', (20, -1))
xtext = wx.TextCtrl(self, -1, "800", style=wx.TE_READONLY|wx.NO_BORDER, size=(50,-1))
xtext.SetBackgroundColour("gray")
ylabel = wx.StaticText(self, -1, 'Y Pixels:', (20, -1))
ytext = wx.TextCtrl(self, -1, "600", size=(50,-1), style=wx.TE_READONLY|wx.NO_BORDER)
ytext.SetBackgroundColour("gray")
tsizer = wx.FlexGridSizer(cols=2, hgap=6, vgap=6)
tsizer.AddMany([xlabel, xtext, ylabel, ytext])
vbox.Add(tsizer, 9, wx.ALL)
self.SetSizer(vbox)
cmaplabel = wx.StaticText(self, -1, 'C Map', (20, -1))
cmapList = ['jet', 'hot', 'cool', 'spectral']
cb = wx.ComboBox(self, -1, "jet", (90, 80), (120, -1), cmapList, style=wx.CB_DROPDOWN)
tsizer = wx.FlexGridSizer(cols=2, hgap=6, vgap=6)
tsizer.AddMany([xlabel, xtext, ylabel, ytext, cmaplabel, cb])
vbox.Add(tsizer, 9, wx.ALL)
self.SetSizer(vbox)
self.Bind(wx.EVT_COMBOBOX, self.OnSelect, cb)
def OnSelect(self, evt):
cmap = evt.GetSelection()
self.SetCmap(cmap)
def SetCmap(self, value):
cmap = value
return cmap
class MyFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, title="Test", size=(1200,1000))
self.top_panel = TopPanel(self)
self.plt_panel = PlotPanel(self)
self.side_panel = InfoPanel(self)
mainSizer = wx.BoxSizer(wx.VERTICAL)
mainSizer.Add(self.top_panel, 0, wx.ALIGN_CENTRE|wx.TOP, 10)
downSizer= wx.BoxSizer(wx.HORIZONTAL)
downSizer.Add(self.plt_panel, 0, wx.EXPAND, 20)
downSizer.Add(self.side_panel, 1, wx.RIGHT, 20)
mainSizer.Add(downSizer, 0, wx.BOTTOM)
self.SetSizer(mainSizer)
self.timer = wx.Timer(self, TIMER_ID)
self.Bind(wx.EVT_TIMER, self.OnTimer,self.timer)
mainSizer.Fit(self)
self.plt_panel.InitPlot()
self.timer = wx.Timer(self, TIMER_ID)
self.Bind(wx.EVT_TIMER, self.OnTimer,self.timer)
self.timer.Start(10)
def OnTimer(self, evt):
self.plt_panel.OnTimer(evt)
app = wx.App(False)
frame = MyFrame()
frame.Show()
app.MainLoop()