python - Multi lines realtime plotting -
i plot multi-lines in python in real-time manner though i'm new language.
i have found codes example work fine can 1 line plotted. me multi-lines please? also, need adjust line width, color, etc. of lines.
the code follows:
# -*- coding: utf-8 -*- """ demo demonstrates how draw dynamic mpl (matplotlib) plot in wxpython application. allows "live" plotting manual zooming specific regions. both x , y axes allow "auto" or "manual" settings. y, auto mode sets scaling of graph see data points. x, auto mode makes graph "follow" data. set x min manual 0 see whole data beginning. note: press enter in 'manual' text box make new value affect plot. eli bendersky (eliben@gmail.com) license: code in public domain last modified: 31.07.2008 """ import os import pprint import random import sys import wx # recommended way use wx mpl wxagg # backend. # import matplotlib matplotlib.use('wxagg') matplotlib.figure import figure matplotlib.backends.backend_wxagg import \ figurecanvaswxagg figcanvas, \ navigationtoolbar2wxagg navigationtoolbar import numpy np import pylab class datagen(object): """ silly class generates pseudo-random data display in plot. """ def __init__(self, init=50): self.data = self.init = init def next(self): self._recalc_data() return self.data def _recalc_data(self): delta = random.uniform(-0.5, 0.5) r = random.random() if r > 0.9: self.data += delta * 15 elif r > 0.8: # attraction initial value delta += (0.5 if self.init > self.data else -0.5) self.data += delta else: self.data += delta class boundcontrolbox(wx.panel): """ static box couple of radio buttons , text box. allows switch between automatic mode , manual mode associated value. """ def __init__(self, parent, id, label, initval): wx.panel.__init__(self, parent, id) self.value = initval box = wx.staticbox(self, -1, label) sizer = wx.staticboxsizer(box, wx.vertical) self.radio_auto = wx.radiobutton(self, -1, label="auto", style=wx.rb_group) self.radio_manual = wx.radiobutton(self, -1, label="manual") self.manual_text = wx.textctrl(self, -1, size=(35,-1), value=str(initval), style=wx.te_process_enter) self.bind(wx.evt_update_ui, self.on_update_manual_text, self.manual_text) self.bind(wx.evt_text_enter, self.on_text_enter, self.manual_text) manual_box = wx.boxsizer(wx.horizontal) manual_box.add(self.radio_manual, flag=wx.align_center_vertical) manual_box.add(self.manual_text, flag=wx.align_center_vertical) sizer.add(self.radio_auto, 0, wx.all, 10) sizer.add(manual_box, 0, wx.all, 10) self.setsizer(sizer) sizer.fit(self) def on_update_manual_text(self, event): self.manual_text.enable(self.radio_manual.getvalue()) def on_text_enter(self, event): self.value = self.manual_text.getvalue() def is_auto(self): return self.radio_auto.getvalue() def manual_value(self): return self.value class graphframe(wx.frame): """ main frame of application """ title = 'demo: dynamic matplotlib graph' #修改下面self.redraw_timer.start(100)数值影响plot下一个数据点的速度,越大速度越慢 def __init__(self): wx.frame.__init__(self, none, -1, self.title) self.datagen = datagen() self.data = [self.datagen.next()] self.paused = false self.create_menu() self.create_status_bar() self.create_main_panel() self.redraw_timer = wx.timer(self) self.bind(wx.evt_timer, self.on_redraw_timer, self.redraw_timer) self.redraw_timer.start(100) def create_menu(self): self.menubar = wx.menubar() menu_file = wx.menu() m_expt = menu_file.append(-1, "&save plot\tctrl-s", "save plot 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) self.menubar.append(menu_file, "&file") self.setmenubar(self.menubar) def create_main_panel(self): self.panel = wx.panel(self) self.init_plot() self.canvas = figcanvas(self.panel, -1, self.fig) self.xmin_control = boundcontrolbox(self.panel, -1, "x min", 0) self.xmax_control = boundcontrolbox(self.panel, -1, "x max", 50) self.ymin_control = boundcontrolbox(self.panel, -1, "y min", 0) self.ymax_control = boundcontrolbox(self.panel, -1, "y max", 100) self.pause_button = wx.button(self.panel, -1, "pause") self.bind(wx.evt_button, self.on_pause_button, self.pause_button) self.bind(wx.evt_update_ui, self.on_update_pause_button, self.pause_button) 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.cb_grid.setvalue(true) self.cb_xlab = wx.checkbox(self.panel, -1, "show x labels", style=wx.align_right) self.bind(wx.evt_checkbox, self.on_cb_xlab, self.cb_xlab) self.cb_xlab.setvalue(true) self.hbox1 = wx.boxsizer(wx.horizontal) self.hbox1.add(self.pause_button, border=5, flag=wx.all | wx.align_center_vertical) self.hbox1.addspacer(20) self.hbox1.add(self.cb_grid, border=5, flag=wx.all | wx.align_center_vertical) self.hbox1.addspacer(10) self.hbox1.add(self.cb_xlab, border=5, flag=wx.all | wx.align_center_vertical) self.hbox2 = wx.boxsizer(wx.horizontal) self.hbox2.add(self.xmin_control, border=5, flag=wx.all) self.hbox2.add(self.xmax_control, border=5, flag=wx.all) self.hbox2.addspacer(24) self.hbox2.add(self.ymin_control, border=5, flag=wx.all) self.hbox2.add(self.ymax_control, border=5, flag=wx.all) self.vbox = wx.boxsizer(wx.vertical) self.vbox.add(self.canvas, 1, flag=wx.left | wx.top | wx.grow) self.vbox.add(self.hbox1, 0, flag=wx.align_left | wx.top) self.vbox.add(self.hbox2, 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 init_plot(self): self.dpi = 100 self.fig = figure((3.0, 3.0), dpi=self.dpi) self.axes = self.fig.add_subplot(111) self.axes.set_axis_bgcolor('gainsboro') self.axes.set_title('very important random data', size=12) pylab.setp(self.axes.get_xticklabels(), fontsize=8) pylab.setp(self.axes.get_yticklabels(), fontsize=8) # plot data line series, , save reference # plotted line series # self.plot_data = self.axes.plot( self.data, linewidth=1, color=(1, 1, 0), )[0] # 修改下面1000可以修改图标put出来的数据量 def draw_plot(self): """ redraws plot """ # when xmin on auto, "follows" xmax produce # sliding window effect. therefore, xmin assigned after # xmax. # if self.xmax_control.is_auto(): xmax = len(self.data) if len(self.data) > 1000 else 1000 else: xmax = int(self.xmax_control.manual_value()) if self.xmin_control.is_auto(): xmin = xmax - 1000 else: xmin = int(self.xmin_control.manual_value()) # ymin , ymax, find minimal , maximal values # in data set , add mininal margin. # # note it's easy change scheme # minimal/maximal value in current display, , not # whole data set. # if self.ymin_control.is_auto(): ymin = round(min(self.data), 0) - 1 else: ymin = int(self.ymin_control.manual_value()) if self.ymax_control.is_auto(): ymax = round(max(self.data), 0) + 1 else: ymax = int(self.ymax_control.manual_value()) self.axes.set_xbound(lower=xmin, upper=xmax) self.axes.set_ybound(lower=ymin, upper=ymax) # anecdote: axes.grid assumes b=true if other flag # given if b set false. # passing flag first statement won't # work. # if self.cb_grid.ischecked(): self.axes.grid(true, color='gray') else: self.axes.grid(false) # using setp here convenient, because get_xticklabels # returns list on 1 needs explicitly # iterate, , setp handles this. # pylab.setp(self.axes.get_xticklabels(), visible=self.cb_xlab.ischecked()) self.plot_data.set_xdata(np.arange(len(self.data))) self.plot_data.set_ydata(np.array(self.data)) self.canvas.draw() def on_pause_button(self, event): self.paused = not self.paused def on_update_pause_button(self, event): label = "resume" if self.paused else "pause" self.pause_button.setlabel(label) def on_cb_grid(self, event): self.draw_plot() def on_cb_xlab(self, event): self.draw_plot() 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 %s" % path) def on_redraw_timer(self, event): # if paused not add data, still redraw plot # (to respond scale modifications, grid change, etc.) # if not self.paused: self.data.append(self.datagen.next()) self.draw_plot() def on_exit(self, event): self.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 = graphframe() app.frame.show() app.mainloop()
Comments
Post a Comment