2016-07-25 6 views
1

저는 파이썬을 처음 접했고 매우 긴 시계열 데이터에 대한 스크롤 플롯을 구현하고자합니다. Matplotlib의 예제는 다음과 같습니다. 내가 링크에서 예제를 실행하면Matplotlib : 플롯 플롯

http://scipy-cookbook.readthedocs.io/items/Matplotlib_ScrollingPlot.html

는, 나는 음모를 스크롤 스크롤, 처음으로 스크롤 반환을 출시 할 때마다 발견했다. 다음 위치로 스크롤 하시겠습니까? 처음부터 다시 스크롤을 시작해야합니다.

왜 그런 일이 일어나고 어떻게 수정해야하는지 이해하고 싶습니다.

답변

3

다음은 개선 된 버전의 예입니다. (부인 : 저는 30 분전에 파기 시작했는데, wx/matplotlib 스크롤바를 사용하기 전에 결코 더 나은 해결책이 없었습니다.)

내가 취한 경로 : 먼저 wx scroll events을 확인한 후 캔버스는 wxPanel에서 파생 된 FigureCanvasWxAgg이며 wxWindow 메서드를 상속받습니다. 여기서 스크롤 위치 처리 방법 GetScrollPosSetScrollPos을 찾을 수 있습니다.

from numpy import arange, sin, pi, float, size 

import matplotlib 
matplotlib.use('WXAgg') 
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg 
from matplotlib.figure import Figure 

import wx 

class MyFrame(wx.Frame): 
    def __init__(self, parent, id): 
     wx.Frame.__init__(self,parent, id, 'scrollable plot', 
       style=wx.DEFAULT_FRAME_STYLE^wx.RESIZE_BORDER, 
       size=(800, 400)) 
     self.panel = wx.Panel(self, -1) 

     self.fig = Figure((5, 4), 75) 
     self.canvas = FigureCanvasWxAgg(self.panel, -1, self.fig) 
     self.scroll_range = 400 
     self.canvas.SetScrollbar(wx.HORIZONTAL, 0, 5, 
           self.scroll_range) 

     sizer = wx.BoxSizer(wx.VERTICAL) 
     sizer.Add(self.canvas, -1, wx.EXPAND) 

     self.panel.SetSizer(sizer) 
     self.panel.Fit() 

     self.init_data() 
     self.init_plot() 

     self.canvas.Bind(wx.EVT_SCROLLWIN, self.OnScrollEvt) 

    def init_data(self): 

     # Generate some data to plot: 
     self.dt = 0.01 
     self.t = arange(0,5,self.dt) 
     self.x = sin(2*pi*self.t) 

     # Extents of data sequence: 
     self.i_min = 0 
     self.i_max = len(self.t) 

     # Size of plot window: 
     self.i_window = 100 

     # Indices of data interval to be plotted: 
     self.i_start = 0 
     self.i_end = self.i_start + self.i_window 

    def init_plot(self): 
     self.axes = self.fig.add_subplot(111) 
     self.plot_data = \ 
        self.axes.plot(self.t[self.i_start:self.i_end], 
           self.x[self.i_start:self.i_end])[0] 

    def draw_plot(self): 

     # Update data in plot: 
     self.plot_data.set_xdata(self.t[self.i_start:self.i_end]) 
     self.plot_data.set_ydata(self.x[self.i_start:self.i_end]) 

     # Adjust plot limits: 
     self.axes.set_xlim((min(self.t[self.i_start:self.i_end]), 
          max(self.t[self.i_start:self.i_end]))) 
     self.axes.set_ylim((min(self.x[self.i_start:self.i_end]), 
          max(self.x[self.i_start:self.i_end]))) 

     # Redraw: 
     self.canvas.draw() 

    def update_scrollpos(self, new_pos): 
     self.i_start = self.i_min + new_pos 
     self.i_end = self.i_min + self.i_window + new_pos 
     self.canvas.SetScrollPos(wx.HORIZONTAL, new_pos) 
     self.draw_plot() 

    def OnScrollEvt(self, event): 
     evtype = event.GetEventType() 

     if evtype == wx.EVT_SCROLLWIN_THUMBTRACK.typeId: 
      pos = event.GetPosition() 
      self.update_scrollpos(pos) 
     elif evtype == wx.EVT_SCROLLWIN_LINEDOWN.typeId: 
      pos = self.canvas.GetScrollPos(wx.HORIZONTAL) 
      self.update_scrollpos(pos + 1) 
     elif evtype == wx.EVT_SCROLLWIN_LINEUP.typeId: 
      pos = self.canvas.GetScrollPos(wx.HORIZONTAL) 
      self.update_scrollpos(pos - 1) 
     elif evtype == wx.EVT_SCROLLWIN_PAGEUP.typeId: 
      pos = self.canvas.GetScrollPos(wx.HORIZONTAL) 
      self.update_scrollpos(pos - 10) 
     elif evtype == wx.EVT_SCROLLWIN_PAGEDOWN.typeId: 
      pos = self.canvas.GetScrollPos(wx.HORIZONTAL) 
      self.update_scrollpos(pos + 10) 
     else: 
      print "unhandled scroll event, type id:", evtype 

class MyApp(wx.App): 
    def OnInit(self): 
     self.frame = MyFrame(parent=None,id=-1) 
     self.frame.Show() 
     self.SetTopWindow(self.frame) 
     return True 

if __name__ == '__main__': 
    app = MyApp() 
    app.MainLoop() 

너무 느린 경우 PAGEUP/PAGEDOWN의 증가분. 대신 만약 당신이, 이벤트가 별도로 취급 자신의 컬렉션을 EVT_SCROLLWIN 대신 특정 이벤트 핸들러를 설정 할 수 있습니다 원하는 경우 또한

후/OnScrollPageUpEvt 등이있을 것이다 elifs