Hello, I need some help with python GUI.
There are one image(image1), two plots(plot1, plot2) in the GUI. I want they share the same axes. I tried with many methods but only found that just one axis is shared. Another problem is the image and plot redraw flicker. How to remove it? Thanks a lot.
#!/usr/bin/env python
"""
Copyright (C) 2003-2005 Jeremy O'Donoghue and others
License: This work is licensed under the PSF. A copy should be included
with this source code, and is also available at
http://www.python.org/psf/license.html
"""
import sys, time, os, gc
import matplotlib
matplotlib.use('WXAgg')
from matplotlib import rcParams
import numpy as npy
import matplotlib.cm as cm
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg
from matplotlib.backends.backend_wx import NavigationToolbar2Wx
from matplotlib.figure import Figure
from wx import *
from matplotlib.ticker import NullFormatter, NullLocator
TIMER_ID = NewId()
class PlotFigure(Frame):
def __init__(self):
Frame.__init__(self, None, -1, "Test embedded wxFigure")
self.fig = Figure((5,4), 75)
self.canvas = FigureCanvasWxAgg(self, -1, self.fig)
self.toolbar = NavigationToolbar2Wx(self.canvas)
self.toolbar.Realize()
rect = [0.075,0.1,0.75,0.85]
self.ax = self.fig.add_axes(rect)
self.axHistx = self.ax.twinx()
self.axHisty = self.ax.twiny()
self.xline, = self.axHistx.plot([], [], animated=True, lw=2)
self.yline, = self.axHisty.plot([], [], animated=True, lw=2)
binwidth = 1
self.xbins = npy.arange(0, 120, binwidth)
self.ybins = npy.arange(0, 120, binwidth)
self.xline.set_xdata(self.xbins)
self.yline.set_ydata(self.ybins)
self.ax.set_xlim([0, 120])
self.ax.set_ylim([120, 0])
self.background = None
# On Windows, default frame size behaviour is incorrect
# you don't need this under Linux
tw, th = self.toolbar.GetSizeTuple()
fw, fh = self.canvas.GetSizeTuple()
self.toolbar.SetSize(Size(fw, th))
# Create a figure manager to manage things
# Now put all into a sizer
sizer = BoxSizer(VERTICAL)
# This way of adding to sizer allows resizing
sizer.Add(self.canvas, 1, LEFT|TOP|GROW)
# Best to allow the toolbar to resize!
sizer.Add(self.toolbar, 0, GROW)
self.SetSizer(sizer)
self.Fit()
EVT_TIMER(self, TIMER_ID, self.onTimer)
def init_plot_data(self):
# jdh you can add a subplot directly from the fig rather than
# the fig manager
self.ax.x = npy.empty((120,120))
self.ax.x.flat = npy.arange(120.0)*2*npy.pi/120.0
self.ax.y = npy.empty((120,120))
self.ax.y.flat = npy.arange(120.0)*2*npy.pi/100.0
self.ax.y = npy.transpose(self.ax.y)
z = npy.fabs(npy.sin(self.ax.x) + npy.cos(self.ax.y))
self.im = self.ax.imshow( z, cmap=cm.jet)#, interpolation='nearest')
self.fig.colorbar(self.im,cmap=cm.jet,orientation='vertical')
def GetToolBar(self):
# You will need to override GetToolBar if you are using an
# unmanaged toolbar in your frame
return self.toolbar
def onTimer(self, evt):
self.ax.x += npy.pi/15
self.ax.y += npy.pi/20
z = npy.fabs(npy.sin(self.ax.x) + npy.cos(self.ax.y))
self.im.set_array(z)
self.onEraseBackground(evt)
self.canvas.draw()
yproject = [0.]*120
for i in range(0, 120):
for j in range (0, 120):
yproject[i] += z[i][j]
yproject[i] /= 120.
xproject = [0.]*120
zt = npy.transpose(z)
for i in range(0, 120):
for j in range (0, 120):
xproject[i] += zt[i][j]
xproject[i] /= 120.
print npy.max(xproject), npy.min(xproject)
self.xline.set_ydata(xproject)
self.axHistx.draw_artist(self.xline)
self.canvas.blit(self.axHistx.get_figure().bbox)
self.yline.set_xdata(yproject)
self.axHisty.draw_artist(self.yline)
self.canvas.blit(self.axHisty.get_figure().bbox)
self.axHistx.set_ylim([0,4])
self.axHisty.set_xlim([0,4])
def onEraseBackground(self, evt):
# this is supposed to prevent redraw flicker on some X servers...
#pass
if __name__ == '__main__':
app = PySimpleApp()
frame = PlotFigure()
frame.init_plot_data()
# Initialise the timer - wxPython requires this to be connected to
# the receiving event handler
t = Timer(frame, TIMER_ID)
t.Start(200)
frame.Show()
app.MainLoop()