This is an archival dump of old wiki content --- see scipy.org for current material.
Please see http://scipy-cookbook.readthedocs.org/

Controlling an Embedded Plot with wx Scrollbars

When plotting a very long sequence in a matplotlib canvas embedded in a wxPython application, it sometimes is useful to be able to display a portion of the sequence without resorting to a scrollable window so that both axes remain visible. Here is how to do so:

   1 from numpy import arange, sin, pi, float, size
   2 
   3 import matplotlib
   4 matplotlib.use('WXAgg')
   5 from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg
   6 from matplotlib.figure import Figure
   7 
   8 import wx
   9 
  10 class MyFrame(wx.Frame):
  11     def __init__(self, parent, id):
  12         wx.Frame.__init__(self,parent, id, 'scrollable plot',
  13                 style=wx.DEFAULT_FRAME_STYLE ^ wx.RESIZE_BORDER,
  14                 size=(800, 400))
  15         self.panel = wx.Panel(self, -1)
  16 
  17         self.fig = Figure((5, 4), 75)
  18         self.canvas = FigureCanvasWxAgg(self.panel, -1, self.fig)
  19         self.scroll_range = 400
  20         self.canvas.SetScrollbar(wx.HORIZONTAL, 0, 5, 
  21                                  self.scroll_range)
  22         
  23         sizer = wx.BoxSizer(wx.VERTICAL)
  24         sizer.Add(self.canvas, -1, wx.EXPAND)
  25 
  26         self.panel.SetSizer(sizer)
  27         self.panel.Fit()
  28 
  29         self.init_data()
  30         self.init_plot()
  31 
  32         self.canvas.Bind(wx.EVT_SCROLLWIN, self.OnScrollEvt)
  33 
  34     def init_data(self):
  35         
  36         # Generate some data to plot:
  37         self.dt = 0.01
  38         self.t = arange(0,5,self.dt)
  39         self.x = sin(2*pi*self.t)
  40 
  41         # Extents of data sequence: 
  42         self.i_min = 0
  43         self.i_max = len(self.t)
  44 
  45         # Size of plot window:       
  46         self.i_window = 100
  47 
  48         # Indices of data interval to be plotted:
  49         self.i_start = 0
  50         self.i_end = self.i_start + self.i_window
  51 
  52     def init_plot(self):
  53         self.axes = self.fig.add_subplot(111)
  54         self.plot_data = \
  55                   self.axes.plot(self.t[self.i_start:self.i_end],
  56                                  self.x[self.i_start:self.i_end])[0]
  57 
  58     def draw_plot(self):
  59 
  60         # Update data in plot:
  61         self.plot_data.set_xdata(self.t[self.i_start:self.i_end])
  62         self.plot_data.set_ydata(self.x[self.i_start:self.i_end])
  63 
  64         # Adjust plot limits:
  65         self.axes.set_xlim((min(self.t[self.i_start:self.i_end]),
  66                            max(self.t[self.i_start:self.i_end])))
  67         self.axes.set_ylim((min(self.x[self.i_start:self.i_end]),
  68                             max(self.x[self.i_start:self.i_end])))
  69 
  70         # Redraw:                  
  71         self.canvas.draw()
  72 
  73     def OnScrollEvt(self, event):
  74 
  75         # Update the indices of the plot:
  76         self.i_start = self.i_min + event.GetPosition()
  77         self.i_end = self.i_min + self.i_window + event.GetPosition()
  78         self.draw_plot()
  79 
  80 class MyApp(wx.App):
  81     def OnInit(self):
  82         self.frame = MyFrame(parent=None,id=-1)
  83         self.frame.Show()
  84         self.SetTopWindow(self.frame)
  85         return True
  86 
  87 if __name__ == '__main__':
  88     app = MyApp()
  89     app.MainLoop()

SciPy: Cookbook/Matplotlib/ScrollingPlot (last edited 2015-10-24 17:48:26 by anonymous)