content: """
  This demo demonstrates how to embed a matplotlib (mpl) plot 
  into a wxPython GUI application, including:
  
  * Using the navigation toolbar
  * Adding data to the plot
  * Dynamically modifying the plot's properties
  * Processing mpl events
  * Saving the plot to a file from a menu
  
  The main goal is to serve as a basis for developing rich wx GUI
  applications featuring mpl plots (using the mpl OO API).
  
  Eli Bendersky (eliben@gmail.com)
  License: this code is in the public domain
  Last modified: 30.07.2008
  """
  import os
  import pprint
  import random
  import wx
  
  # The recommended way to use wx with mpl is with the WXAgg
  # backend. 
  #
  import matplotlib
  matplotlib.use('WXAgg')
  from matplotlib.figure import Figure
  from matplotlib.backends.backend_wxagg import \
      FigureCanvasWxAgg as FigCanvas, \
      NavigationToolbar2WxAgg as NavigationToolbar
  
  
  class BarsFrame(wx.Frame):
      """ The main frame of the application
      """
      title = 'Demo: wxPython with matplotlib'
      
      def __init__(self):
          wx.Frame.__init__(self, None, -1, self.title)
          
          self.data = [5, 6, 9, 14]
          
          self.create_menu()
          self.create_status_bar()
          self.create_main_panel()
          
          self.textbox.SetValue(' '.join(map(str, self.data)))
          self.draw_figure()
  
      def create_menu(self):
          self.menubar = wx.MenuBar()
          
          menu_file = wx.Menu()
          m_expt = menu_file.Append(-1, "&Save plot\tCtrl-S", "Save plot to file")
          self.Bind(wx.EVT_MENU, self.on_save_plot, m_expt)
          menu_file.AppendSeparator()
          m_exit = menu_file.Append(-1, "E&xit\tCtrl-X", "Exit")
          self.Bind(wx.EVT_MENU, self.on_exit, m_exit)
          
          menu_help = wx.Menu()
          m_about = menu_help.Append(-1, "&About\tF1", "About the demo")
          self.Bind(wx.EVT_MENU, self.on_about, m_about)
          
          self.menubar.Append(menu_file, "&File")
          self.menubar.Append(menu_help, "&Help")
          self.SetMenuBar(self.menubar)
  
      def create_main_panel(self):
          """ Creates the main panel with all the controls on it:
               * mpl canvas 
               * mpl navigation toolbar
               * Control panel for interaction
          """
          self.panel = wx.Panel(self)
          
          # Create the mpl Figure and FigCanvas objects. 
          # 5x4 inches, 100 dots-per-inch
          #
          self.dpi = 100
          self.fig = Figure((5.0, 4.0), dpi=self.dpi)
          self.canvas = FigCanvas(self.panel, -1, self.fig)
          
          # Since we have only one plot, we can use add_axes 
          # instead of add_subplot, but then the subplot
          # configuration tool in the navigation toolbar wouldn't
          # work.
          #
          self.axes = self.fig.add_subplot(111)
          
          # Bind the 'pick' event for clicking on one of the bars
          #
          self.canvas.mpl_connect('pick_event', self.on_pick)
          
          self.textbox = wx.TextCtrl(
              self.panel, 
              size=(200,-1),
              style=wx.TE_PROCESS_ENTER)
          self.Bind(wx.EVT_TEXT_ENTER, self.on_text_enter, self.textbox)
          
          self.drawbutton = wx.Button(self.panel, -1, "Draw!")
          self.Bind(wx.EVT_BUTTON, self.on_draw_button, self.drawbutton)
  
          self.cb_grid = wx.CheckBox(self.panel, -1, 
              "Show Grid",
              style=wx.ALIGN_RIGHT)
          self.Bind(wx.EVT_CHECKBOX, self.on_cb_grid, self.cb_grid)
  
          self.slider_label = wx.StaticText(self.panel, -1, 
              "Bar width (%): ")
          self.slider_width = wx.Slider(self.panel, -1, 
              value=20, 
              minValue=1,
              maxValue=100,
              style=wx.SL_AUTOTICKS | wx.SL_LABELS)
          self.slider_width.SetTickFreq(10, 1)
          self.Bind(wx.EVT_COMMAND_SCROLL_THUMBTRACK, self.on_slider_width, self.slider_width)
  
          # Create the navigation toolbar, tied to the canvas
          #
          self.toolbar = NavigationToolbar(self.canvas)
          
          #
          # Layout with box sizers
          #
          
          self.vbox = wx.BoxSizer(wx.VERTICAL)
          self.vbox.Add(self.canvas, 1, wx.LEFT | wx.TOP | wx.GROW)
          self.vbox.Add(self.toolbar, 0, wx.EXPAND)
          self.vbox.AddSpacer(10)
          
          self.hbox = wx.BoxSizer(wx.HORIZONTAL)
          flags = wx.ALIGN_LEFT | wx.ALL | wx.ALIGN_CENTER_VERTICAL
          self.hbox.Add(self.textbox, 0, border=3, flag=flags)
          self.hbox.Add(self.drawbutton, 0, border=3, flag=flags)
          self.hbox.Add(self.cb_grid, 0, border=3, flag=flags)
          self.hbox.AddSpacer(30)
          self.hbox.Add(self.slider_label, 0, flag=flags)
          self.hbox.Add(self.slider_width, 0, border=3, flag=flags)
          
          self.vbox.Add(self.hbox, 0, flag = wx.ALIGN_LEFT | wx.TOP)
          
          self.panel.SetSizer(self.vbox)
          self.vbox.Fit(self)
      
      def create_status_bar(self):
          self.statusbar = self.CreateStatusBar()
  
      def draw_figure(self):
          """ Redraws the figure
          """
          str = self.textbox.GetValue()
          self.data = map(int, str.split())
          x = range(len(self.data))
  
          # clear the axes and redraw the plot anew
          #
          self.axes.clear()        
          self.axes.grid(self.cb_grid.IsChecked())
          
          self.axes.bar(
              left=x, 
              height=self.data, 
              width=self.slider_width.GetValue() / 100.0, 
              align='center', 
              alpha=0.44,
              picker=5)
          
          self.canvas.draw()
      
      def on_cb_grid(self, event):
          self.draw_figure()
      
      def on_slider_width(self, event):
          self.draw_figure()
      
      def on_draw_button(self, event):
          self.draw_figure()
      
      def on_pick(self, event):
          # The event received here is of the type
          # matplotlib.backend_bases.PickEvent
          #
          # It carries lots of information, of which we're using
          # only a small amount here.
          # 
          box_points = event.artist.get_bbox().get_points()
          msg = "You've clicked on a bar with coords:\n %s" % box_points
          
          dlg = wx.MessageDialog(
              self, 
              msg, 
              "Click!",
              wx.OK | wx.ICON_INFORMATION)
  
          dlg.ShowModal() 
          dlg.Destroy()        
      
      def on_text_enter(self, event):
          self.draw_figure()
  
      def on_save_plot(self, event):
          file_choices = "PNG (*.png)|*.png"
          
          dlg = wx.FileDialog(
              self, 
              message="Save plot as...",
              defaultDir=os.getcwd(),
              defaultFile="plot.png",
              wildcard=file_choices,
              style=wx.SAVE)
          
          if dlg.ShowModal() == wx.ID_OK:
              path = dlg.GetPath()
              self.canvas.print_figure(path, dpi=self.dpi)
              self.flash_status_message("Saved to %s" % path)
          
      def on_exit(self, event):
          self.Destroy()
          
      def on_about(self, event):
          msg = """ A demo using wxPython with matplotlib:
          
           * Use the matplotlib navigation bar
           * Add values to the text box and press Enter (or click "Draw!")
           * Show or hide the grid
           * Drag the slider to modify the width of the bars
           * Save the plot to a file using the File menu
           * Click on a bar to receive an informative message
          """
          dlg = wx.MessageDialog(self, msg, "About", wx.OK)
          dlg.ShowModal()
          dlg.Destroy()
      
      def flash_status_message(self, msg, flash_len_ms=1500):
          self.statusbar.SetStatusText(msg)
          self.timeroff = wx.Timer(self)
          self.Bind(
              wx.EVT_TIMER, 
              self.on_flash_status_off, 
              self.timeroff)
          self.timeroff.Start(flash_len_ms, oneShot=True)
      
      def on_flash_status_off(self, event):
          self.statusbar.SetStatusText('')
  
  
  if __name__ == '__main__':
      app = wx.PySimpleApp()
      app.frame = BarsFrame()
      app.frame.Show()
      app.MainLoop()
  
  