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()

Any suggestion is great appreciated.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.