0

I have a simple wxFrame and two panels in it. i want one of the panels to show a matplotlib bar chart. I learnt to use the chart, but the show() function that I use gives me the chart in a new window.

 import wx
import wx.grid as gridlib
import os
import Image
import pylab as p

class PanelOne(wx.Panel):
    def __init__(self, parent):
        """Constructor"""
        wx.Panel.__init__(self, parent=parent)
        #txt = wx.TextCtrl(self)
        button =wx.Button(self, label="Save", pos=(200, 325))
        button.Bind(wx.EVT_BUTTON, parent.onSwitchPanels)

class PanelTwo(wx.Panel):
    def __init__(self, parent):
        """Constructor"""
        wx.Panel.__init__(self, parent=parent)


        sizer = wx.BoxSizer(wx.VERTICAL)
        self.SetSizer(sizer)
        fig=p.figure()
        ax=fig.add_subplot(1,1,1)
        x=[1,2,3]
        y=[4,6,3]
        ax.bar(x,y)
        p.show()

class MyForm(wx.Frame):

    def __init__(self):
        wx.Frame.__init__(self, None, wx.ID_ANY,
                          "Panel Switch",
                          size=(800,600))

        self.panel_one = PanelOne(self)
        self.panel_two = PanelTwo(self)
        self.panel_two.Hide()

        self.sizer = wx.BoxSizer(wx.VERTICAL)
        self.sizer.Add(self.panel_one, 1, wx.EXPAND)
        self.sizer.Add(self.panel_two, 1, wx.EXPAND)
        self.SetSizer(self.sizer)

        menubar = wx.MenuBar()
        fileMenu = wx.Menu()
        switch_panels_menu_item = fileMenu.Append(wx.ID_ANY,
                                                  "Switch Panels",
                                                  "Some text")
        self.Bind(wx.EVT_MENU, self.onSwitchPanels,
                  switch_panels_menu_item)
        menubar.Append(fileMenu, '&File')
        self.SetMenuBar(menubar)
-------------------------------------------------------------------
    def onSwitchPanels(self, event):

        if self.panel_one.IsShown():
           self.SetTitle("Panel Two Showing")
           self.panel_one.Hide()
           self.panel_two.Show()
        else:
           self.SetTitle("Panel One Showing")
           self.panel_one.Show()
           self.panel_two.Hide()
        self.Layout()

    if __name__ == "__main__":
    app = wx.App(False)
    frame = MyForm()
    frame.Show()
    app.MainLoop()

What happens is that I get the chart in a new matplotlib window and when I close that, my frame appears. I need the chart to be in the second panel of the frame.

I tried reading This , but did not quite help me.

Community
  • 1
  • 1
Kumaran Senapathy
  • 1,233
  • 4
  • 18
  • 30

1 Answers1

0

The pyplot functions you are using (p.figure) have the primary purpose of taking care of all the GUI details (which works at cross purposes to what you want). What you want to to is embed matplotlib in your pre-existing gui. For how to do this, see these examples.

This code is pulled from embedding_in_wx2.py to protect against link-rot:

#!/usr/bin/env python
"""
An example of how to use wx or wxagg in an application with the new
toolbar - comment out the setA_toolbar line for no toolbar
"""
# Used to guarantee to use at least Wx2.8
import wxversion
wxversion.ensureMinimal('2.8')
from numpy import arange, sin, pi

import matplotlib

# uncomment the following to use wx rather than wxagg
#matplotlib.use('WX')
#from matplotlib.backends.backend_wx import FigureCanvasWx as FigureCanvas

# comment out the following to use wx rather than wxagg
matplotlib.use('WXAgg')
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas

from matplotlib.backends.backend_wx import NavigationToolbar2Wx

from matplotlib.figure import Figure
import wx

class CanvasFrame(wx.Frame):

    def __init__(self):
        wx.Frame.__init__(self,None,-1,
                         'CanvasFrame',size=(550,350))

        self.SetBackgroundColour(wx.NamedColour("WHITE"))
        self.figure = Figure()
        self.axes = self.figure.add_subplot(111)
        t = arange(0.0,3.0,0.01)
        s = sin(2*pi*t)
        self.axes.plot(t,s)
        self.canvas = FigureCanvas(self, -1, self.figure)
        self.sizer = wx.BoxSizer(wx.VERTICAL)
        self.sizer.Add(self.canvas, 1, wx.LEFT | wx.TOP | wx.GROW)
        self.SetSizer(self.sizer)
        self.Fit()

    def OnPaint(self, event):
        self.canvas.draw()

class App(wx.App):
    def OnInit(self):
        'Create the main window and insert the custom frame'
        frame = CanvasFrame()
        frame.Show(True)
        return True

app = App(0)
app.MainLoop()
tacaswell
  • 84,579
  • 22
  • 210
  • 199
  • This works on the frame. But I am looking for to embed the chart inside one of the panels. And Bar chart at that. I tried your code inside a panel, but failed. I used the pylot because of my inability to bring up bar charts. – Kumaran Senapathy Feb 26 '13 at 16:07
  • I can't do anything with 'it failed'. You should edit your question with _exactly_ what you tried or open a new question. To get bar plots instead of lines, just change `self.axes.plot(...)` -> `self.axes.bar(...)`. – tacaswell Feb 26 '13 at 16:41
  • Actually I tweaked in a bit and changed the plot to bar like u said and it works fine. Thanks. – Kumaran Senapathy Feb 26 '13 at 16:51
  • glad hear! Sorry I was snippy, haven't had enough coffee yet today. – tacaswell Feb 26 '13 at 16:55
  • No problem. Helped a lot. I am just learning python and trying to get a lot of plots in a single window. :) I need coffee too. Cheers. – Kumaran Senapathy Feb 26 '13 at 16:56