我是Python的新手,我想爲一個很長時間的系列數據實現一個滾動圖。我從Matplotlib中找到了一個例子,如下所示。Matplotlib:滾動圖
http://scipy-cookbook.readthedocs.io/items/Matplotlib_ScrollingPlot.html
當我從鏈接運行的例子中,我發現我每次滾動的情節和釋放滾動條,滾動條返回到最初的時間。想滾動到下一個位置?我需要再次從頭開始滾動。
我想了解它爲什麼會發生,以及如何解決它。
我是Python的新手,我想爲一個很長時間的系列數據實現一個滾動圖。我從Matplotlib中找到了一個例子,如下所示。Matplotlib:滾動圖
http://scipy-cookbook.readthedocs.io/items/Matplotlib_ScrollingPlot.html
當我從鏈接運行的例子中,我發現我每次滾動的情節和釋放滾動條,滾動條返回到最初的時間。想滾動到下一個位置?我需要再次從頭開始滾動。
我想了解它爲什麼會發生,以及如何解決它。
下面是該示例的改進版本。 (免責聲明:我半小時前開始挖掘它,以前從未使用過wx/matplotlib滾動條,因此可能會有更好的解決方案。)
我採用的路徑:首先檢查wx scroll events,然後發現畫布是從wxPanel派生的FigureCanvasWxAgg,繼承wxWindow方法。在那裏你可以找到滾動位置處理方法GetScrollPos
和SetScrollPos
。
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
的,然後代替如果/ elifs會有OnScrollPageUpEvt等