trouble redrawing the canvas when embedding the matplotlib figure in wxpython , also tooltip not being enabled when matplotlib figure placed in wxpython

Hi all,

I am having trouble redrawing the canvas when embedding the simple matplotlib graph into wxpython.
I tried creating the required GUI using the XRCed.
My aim is to display two check boxes, one with Sin and one with Cos signal. And then a show button.
By default both the checkboxes are clicked and a Sin signal is displayed.
If SinCheckbox is clicked, I want a sin signal. If Cos is clicked, I wanted a Cos Signal. If both are checked I wanted a Tan signal to be displayed in the figure.
The problem i am facing is, when I am trying to draw on the canvas for the figure, I thought the old canvas gets cleared and draw() redraws the figure. But this does not seem to be the case. I still see the old figure and new plot being drawn on the old plot.

Also I tried placing the tooltips but they doesnt seem to come up.

Please find the code I have used for the same. I tried to modify the code in the matplotlib examples for embedding matplotlib in wxpython.
Also attaching to this email is the xrc code generated using XRCed

MyApp- class creates the required layout.
PlotPanel class is responsible for creating the figure, embedding the matplotlibfigure inside the canvas and redrawing it through method ‘repaint’ i defined in it.

I am getting an object of PlotPanel in the MyApp instance and calling the plot function.

import wxversion
wxversion.ensureMinimal(‘2.8’)

import sys, time, os, gc
import matplotlib
matplotlib.use(‘WXAgg’)
import matplotlib.cm as cm
import matplotlib.cbook as cbook
from matplotlib.backends.backend_wxagg import Toolbar, FigureCanvasWxAgg,
NavigationToolbar2WxAgg as NavigationToolbar
from matplotlib.figure import Figure
import numpy as npy
from pylab import get_current_fig_manager as gcfm
import wx
import wx.xrc as xrc
import matplotlib as mpl
mpl.use(‘WXAgg’)
mpl.interactive(False)
ERR_TOL = 1e-5 # floating point slop for peak-detection
matplotlib.rc(‘image’, origin=‘lower’)

class PlotPanel(wx.Panel):

def __init__(self, parent):
    wx.Panel.__init__(self, parent, -1)
    self.tooltip = wx.ToolTip(tip='tip with a long %s line and a newline\n' % (' '*100)) # needs to be added to getover the bug with tooltip.
    self.fig = Figure((5,4), 200)
    self.a = self.fig.add_subplot(111)
    #self.fig = Figure(0)
    self.canvas = FigureCanvasWxAgg(self, -1, self.fig)
    #self.toolbar = Toolbar(self.canvas) #matplotlib toolbar
    self.toolbar = NavigationToolbar(self.canvas)
    self.toolbar.Realize()
    # Now put all into a sizer
    sizer = wx.BoxSizer(wx.VERTICAL)
    # This way of adding to sizer allows resizing
    sizer.Add(self.canvas, 1, wx.LEFT|wx.BOTTOM|wx.GROW)
    # Best to allow the toolbar to resize!
    sizer.Add(self.toolbar, 0, wx.GROW)
    self.SetSizer(sizer)
    self.Fit()

def init_plot_data(self):

    self.x=npy.linspace(0, 6 * npy.pi, 500)
    self.y=npy.sin(self.x)
    #self.x, self.y = npy.meshgrid(x, y)
    print 'before the plotting'
    self.myGraph = self.a.plot(self.x,self.y)
    print 'after the plotting'
   
    self.toolbar.update()
    gcfm().canvas.SetToolTip(self.tooltip)
    self.tooltip.Enable(False)
    self.tooltip.SetDelay(0)
    self.fig.canvas.mpl_connect('motion_notify_event',self._onMotion)

def GetToolBar(self):
    # You will need to override GetToolBar if you are using an
    # unmanaged toolbar in your frame
    return self.toolbar

def _onMotion(self,event) :
    tip='X:{0} Y:{1}'.format(event.xdata,event.ydata)
    print tip
    self.tooltip.SetTip(tip)
    self.tooltip.Enable(True)
   
def repaint(self):
    self.canvas.draw()

class MyApp(wx.App):

def OnInit(self):
    #xrcfile = cbook.get_sample_data('graphing_tool.xrc', asfileobj=False)
    xrcfile='U:\graphing_tool\modularised\\version_13_13th July\gtool.xrc'
    print 'loading', xrcfile

    self.res = xrc.XmlResource(xrcfile)
   
    # main frame and panel ---------

    self.frame = self.res.LoadFrame(None,"mainFrame")
    print 'RAVI: Frame is :',self.frame
    self.panel = xrc.XRCCTRL(self.frame,"mainPanel")

    # matplotlib panel -------------

    # container for matplotlib panel (I like to make a container
    # panel for our panel so I know where it'll go when in XRCed.)
    plot_container = xrc.XRCCTRL(self.frame,"signalplot")
    sizer = wx.BoxSizer(wx.VERTICAL)

    # matplotlib panel itself
    self.plotpanel = PlotPanel(plot_container)
    self.plotpanel.init_plot_data()

    sizer.Add(self.plotpanel, 1, wx.EXPAND)
    plot_container.SetSizer(sizer)

    # onex checkbox

    self.sin_checkbox = xrc.XRCCTRL(self.frame,'sin')
   
    # lte checkbox

    self.cos_checkbox = xrc.XRCCTRL(self.frame,'cos')

    ## display button
    display_button= xrc.XRCCTRL(self.frame,'display')
    wx.EVT_BUTTON(display_button,display_button.GetId(),self.onDisplay)
   
   
    # final setup ------------------

    sizer = self.panel.GetSizer()
    self.frame.Show(1)

    self.SetTopWindow(self.frame)

    return True

def onDisplay(self,event):

    if self.sin_checkbox.IsChecked() and not self.cos_checkbox.IsChecked():
        print 'showing sin signal'
        self.plotFigure(1)
       
    elif not self.sin_checkbox.IsChecked() and self.cos_checkbox.IsChecked():
        print 'showing cos signal'
        self.plotFigure(2)
    elif self.sin_checkbox.IsChecked() and self.cos_checkbox.IsChecked() :
        print 'showing Tan signal'
        self.plotFigure(3)
    else:
        msg= 'Not showing either sin or cos signal. Click on either of the signals'

def plotFigure(self,option):
    if option == 1:
        self.plotpanel.y=npy.sin(self.plotpanel.x)
        #self.x, self.y = npy.meshgrid(x, y)
        print 'before the plotting sin'
        self.plotpanel.myGraph = self.plotpanel.a.plot(self.plotpanel.x,self.plotpanel.y)
        print 'after the plotting'
       
        self.plotpanel.repaint()
    elif option == 2:
        #self.plotpanel.fig.clf(False)
        #self.plotpanel.canvas.Clear()
        self.plotpanel.y=npy.cos(self.plotpanel.x)
        #self.x, self.y = npy.meshgrid(x, y)
        print 'before the plotting cos'
        self.plotpanel.myGraph = self.plotpanel.a.plot(self.plotpanel.x,self.plotpanel.y)
        print 'after the plotting'
        self.plotpanel.repaint()
    else:
        #self.plotpanel.fig.clf(False)
        #self.plotpanel.canvas.Clear()
        self.plotpanel.y=npy.tan(self.plotpanel.x)
        #self.x, self.y = npy.meshgrid(x, y)
        print 'before the plotting Tan'
        self.plotpanel.myGraph = self.plotpanel.a.plot(self.plotpanel.x,self.plotpanel.y)
        print 'after the plotting'
        self.plotpanel.repaint()

if name == ‘main’:
app = MyApp(0)
app.MainLoop()

gtool.xrc (1.66 KB)

···

Thanks,

Ravikanth

Reposting it as the content of my query in my previous post on the website.

···

Hi all,

I am having trouble redrawing the canvas when embedding the simple matplotlib graph into wxpython.
I tried creating the required GUI using the XRCed.
My aim is to display two check boxes, one with Sin and one with Cos signal. And then a show button.

By default both the checkboxes are clicked and a Sin signal is displayed.
If SinCheckbox is clicked, I want a sin signal. If Cos is clicked, I wanted a Cos Signal. If both are checked I wanted a Tan signal to be displayed in the figure.

The problem i am facing is, when I am trying to draw on the canvas for the figure, I thought the old canvas gets cleared and draw() redraws the figure. But this does not seem to be the case. I still see the old figure and new plot being drawn on the old plot.

Also I tried placing the tooltips but they doesnt seem to come up.

Please find the code I have used for the same. I tried to modify the code in the matplotlib examples for embedding matplotlib in wxpython.

Also attaching to this email is the xrc code generated using XRCed

MyApp- class creates the required layout.
PlotPanel class is responsible for creating the figure, embedding the matplotlibfigure inside the canvas and redrawing it through method ‘repaint’ i defined in it.

I am getting an object of PlotPanel in the MyApp instance and calling the plot function.

import wxversion
wxversion.ensureMinimal(‘2.8’)

import sys, time, os, gc
import matplotlib

matplotlib.use(‘WXAgg’)
import matplotlib.cm as cm
import matplotlib.cbook as cbook
from matplotlib.backends.backend_wxagg import Toolbar, FigureCanvasWxAgg, \

 NavigationToolbar2WxAgg as NavigationToolbar

from matplotlib.figure import Figure
import numpy as npy
from pylab import get_current_fig_manager as gcfm
import wx
import wx.xrc as xrc
import matplotlib as mpl
mpl.use(‘WXAgg’)
mpl.interactive(False)

ERR_TOL = 1e-5 # floating point slop for peak-detection
matplotlib.rc(‘image’, origin=‘lower’)

class PlotPanel(wx.Panel):

def __init__(self, parent):
    wx.Panel.__init__(self, parent, -1)


    self.tooltip = wx.ToolTip(tip='tip with a long %s line and a newline\n' % (' '*100)) # needs to be added to getover the bug with tooltip.
    self.fig = Figure((5,4), 200)
    self.a = self.fig.add_subplot(111)


    #self.fig = Figure(0)
    self.canvas = FigureCanvasWxAgg(self, -1, self.fig)
    #self.toolbar = Toolbar(self.canvas) #matplotlib toolbar
    self.toolbar = NavigationToolbar(self.canvas)


    self.toolbar.Realize()
    # Now put all into a sizer
    sizer = wx.BoxSizer(wx.VERTICAL)
    # This way of adding to sizer allows resizing
    sizer.Add(self.canvas, 1, wx.LEFT|wx.BOTTOM|wx.GROW)


    # Best to allow the toolbar to resize!
    sizer.Add(self.toolbar, 0, wx.GROW)
    self.SetSizer(sizer)
    self.Fit()

def init_plot_data(self):

    self.x=npy.linspace(0, 6 * npy.pi, 500)


    self.y=npy.sin(self.x)
    #self.x, self.y = npy.meshgrid(x, y)
    print 'before the plotting'
    self.myGraph = self.a.plot(self.x,self.y)
    print 'after the plotting'


   
    self.toolbar.update()
    gcfm().canvas.SetToolTip(self.tooltip)
    self.tooltip.Enable(False)
    self.tooltip.SetDelay(0)
    self.fig.canvas.mpl_connect('motion_notify_event',self._onMotion)



def GetToolBar(self):
    # You will need to override GetToolBar if you are using an
    # unmanaged toolbar in your frame
    return self.toolbar

def _onMotion(self,event) :


    tip='X:{0} Y:{1}'.format(event.xdata,event.ydata)
    print tip
    self.tooltip.SetTip(tip)
    self.tooltip.Enable(True)
   
def repaint(self):
    self.canvas.draw()

class MyApp(wx.App):

def OnInit(self):
    #xrcfile = cbook.get_sample_data('graphing_tool.xrc', asfileobj=False)
    xrcfile='U:\graphing_tool\modularised\\version_13_13th July\gtool.xrc'


    print 'loading', xrcfile

    self.res = xrc.XmlResource(xrcfile)
   
    # main frame and panel ---------

    self.frame = self.res.LoadFrame(None,"mainFrame")


    print 'RAVI: Frame is :',self.frame
    self.panel = xrc.XRCCTRL(self.frame,"mainPanel")

    # matplotlib panel -------------

    # container for matplotlib panel (I like to make a container


    # panel for our panel so I know where it'll go when in XRCed.)
    plot_container = xrc.XRCCTRL(self.frame,"signalplot")
    sizer = wx.BoxSizer(wx.VERTICAL)

    # matplotlib panel itself


    self.plotpanel = PlotPanel(plot_container)
    self.plotpanel.init_plot_data()

    sizer.Add(self.plotpanel, 1, wx.EXPAND)
    plot_container.SetSizer(sizer)

    # onex checkbox



    self.sin_checkbox = xrc.XRCCTRL(self.frame,'sin')
   
    # lte checkbox

    self.cos_checkbox = xrc.XRCCTRL(self.frame,'cos')

    ## display button
    display_button= xrc.XRCCTRL(self.frame,'display')


    wx.EVT_BUTTON(display_button,display_button.GetId(),self.onDisplay)
   
   
    # final setup ------------------

    sizer = self.panel.GetSizer()
    self.frame.Show(1)



    self.SetTopWindow(self.frame)

    return True

def onDisplay(self,event):

    if self.sin_checkbox.IsChecked() and not self.cos_checkbox.IsChecked():
        print 'showing sin signal'


        self.plotFigure(1)
       
    elif not self.sin_checkbox.IsChecked() and self.cos_checkbox.IsChecked():
        print 'showing cos signal'
        self.plotFigure(2)
    elif self.sin_checkbox.IsChecked() and self.cos_checkbox.IsChecked() :


        print 'showing Tan signal'
        self.plotFigure(3)
    else:
        msg= 'Not showing either sin or cos signal. Click on either of the signals'

def plotFigure(self,option):


    if option == 1:
        self.plotpanel.y=npy.sin(self.plotpanel.x)
        #self.x, self.y = npy.meshgrid(x, y)
        print 'before the plotting sin'
        self.plotpanel.myGraph = self.plotpanel.a.plot(self.plotpanel.x,self.plotpanel.y)


        print 'after the plotting'
       
        self.plotpanel.repaint()
    elif option == 2:
        #self.plotpanel.fig.clf(False)
        #self.plotpanel.canvas.Clear()


        self.plotpanel.y=npy.cos(self.plotpanel.x)
        #self.x, self.y = npy.meshgrid(x, y)
        print 'before the plotting cos'
        self.plotpanel.myGraph = self.plotpanel.a.plot(self.plotpanel.x,self.plotpanel.y)


        print 'after the plotting'
        self.plotpanel.repaint()
    else:
        #self.plotpanel.fig.clf(False)
        #self.plotpanel.canvas.Clear()
        self.plotpanel.y=npy.tan(self.plotpanel.x)


        #self.x, self.y = npy.meshgrid(x, y)
        print 'before the plotting Tan'
        self.plotpanel.myGraph = self.plotpanel.a.plot(self.plotpanel.x,self.plotpanel.y)
        print 'after the plotting'


        self.plotpanel.repaint()

if name == ‘main’:
app = MyApp(0)
app.MainLoop()


Thanks,

Ravikanth


Regards,

RaviKanth VN Vanapalli

MS - Telecommunications Engineering

The University of Texas at Dallas, Richardson, TX
Ph: (571) 420 0656

Email: vvnrk.vanapalli@…2015…87…