def __init__(self, panel, notify, settings, status, remoteControl): self.panel = panel self.notify = notify self.plot = None self.settings = settings self.status = status self.remoteControl = remoteControl self.spectrum = None self.isLimited = None self.limit = None self.extent = None self.annotate = None self.isDrawing = False self.toolTip = wx.ToolTip('') self.mouseSelect = None self.mouseZoom = None self.measureTable = None self.background = None self.selectStart = None self.selectEnd = None self.menuClearSelect = [] self.measure = None self.show = None self.doDraw = False wx.Panel.__init__(self, panel) self.figure = matplotlib.figure.Figure(facecolor='white') self.figure.set_size_inches(0, 0) self.canvas = FigureCanvas(self, -1, self.figure) self.canvas.SetToolTip(self.toolTip) self.measureTable = PanelMeasure(self, settings) self.toolbar = NavigationToolbar(self.canvas, self, settings, self.__hide_overlay) self.toolbar.Realize() vbox = wx.BoxSizer(wx.VERTICAL) vbox.Add(self.canvas, 1, wx.EXPAND) vbox.Add(self.measureTable, 0, wx.EXPAND) vbox.Add(self.toolbar, 0, wx.EXPAND) self.SetSizer(vbox) vbox.Fit(self) self.create_plot() self.canvas.mpl_connect('button_press_event', self.__on_press) self.canvas.mpl_connect('figure_enter_event', self.__on_enter) self.canvas.mpl_connect('axes_leave_event', self.__on_leave) self.canvas.mpl_connect('motion_notify_event', self.__on_motion) self.canvas.mpl_connect('draw_event', self.__on_draw) self.canvas.mpl_connect('idle_event', self.__on_idle) self.Bind(wx.EVT_SIZE, self.__on_size) self.timer = wx.Timer(self) self.Bind(wx.EVT_TIMER, self.__on_timer, self.timer)
class PanelGraph(wx.Panel): def __init__(self, panel, notify, settings, status, remoteControl): self.panel = panel self.notify = notify self.plot = None self.settings = settings self.status = status self.remoteControl = remoteControl self.spectrum = None self.isLimited = None self.limit = None self.extent = None self.annotate = None self.isDrawing = False self.toolTip = wx.ToolTip('') self.mouseSelect = None self.mouseZoom = None self.measureTable = None self.background = None self.selectStart = None self.selectEnd = None self.menuClearSelect = [] self.measure = None self.show = None self.doDraw = False wx.Panel.__init__(self, panel) self.figure = matplotlib.figure.Figure(facecolor='white') self.figure.set_size_inches(0, 0) self.canvas = FigureCanvas(self, -1, self.figure) self.canvas.SetToolTip(self.toolTip) self.measureTable = PanelMeasure(self, settings) self.toolbar = NavigationToolbar(self.canvas, self, settings, self.__hide_overlay) self.toolbar.Realize() vbox = wx.BoxSizer(wx.VERTICAL) vbox.Add(self.canvas, 1, wx.EXPAND) vbox.Add(self.measureTable, 0, wx.EXPAND) vbox.Add(self.toolbar, 0, wx.EXPAND) self.SetSizer(vbox) vbox.Fit(self) self.create_plot() self.canvas.mpl_connect('button_press_event', self.__on_press) self.canvas.mpl_connect('figure_enter_event', self.__on_enter) self.canvas.mpl_connect('axes_leave_event', self.__on_leave) self.canvas.mpl_connect('motion_notify_event', self.__on_motion) self.canvas.mpl_connect('draw_event', self.__on_draw) self.canvas.mpl_connect('idle_event', self.__on_idle) self.Bind(wx.EVT_SIZE, self.__on_size) self.timer = wx.Timer(self) self.Bind(wx.EVT_TIMER, self.__on_timer, self.timer) def __set_fonts(self): axes = self.plot.get_axes() if axes is not None: axes.xaxis.label.set_size('small') axes.yaxis.label.set_size('small') if self.settings.display == Display.SURFACE: axes.zaxis.label.set_size('small') axes.tick_params(axis='both', which='major', labelsize='small') axes = self.plot.get_axes_bar() if axes is not None: axes.tick_params(axis='both', which='major', labelsize='small') def __enable_menu(self, state): for menu in self.menuClearSelect: menu.Enable(state) def __on_press(self, event): if self.settings.clickTune and matplotlib.__version__ >= '1.2' and event.dblclick: frequency = int(event.xdata * 1e6) self.remoteControl.tune(frequency) elif isinstance(self.plot, PlotterPreview): self.plot.to_front() def __on_enter(self, _event): self.toolTip.Enable(False) def __on_leave(self, _event): self.toolTip.Enable(True) self.status.set_info('', level=None) def __on_motion(self, event): axes = self.plot.get_axes() axesBar = self.plot.get_axes_bar() xpos = event.xdata ypos = event.ydata text = "" if (xpos is None or ypos is None or self.spectrum is None or event.inaxes is None): spectrum = None elif event.inaxes == axesBar: spectrum = None level = self.plot.get_bar().norm.inverse(ypos) text = "{}".format(format_precision(self.settings, level=level)) elif self.settings.display == Display.PLOT: timeStamp = max(self.spectrum) spectrum = self.spectrum[timeStamp] elif self.settings.display == Display.SPECT: timeStamp = num2epoch(ypos) if timeStamp in self.spectrum: spectrum = self.spectrum[timeStamp] else: nearest = min(self.spectrum.keys(), key=lambda k: abs(k - timeStamp)) spectrum = self.spectrum[nearest] elif self.settings.display == Display.SURFACE: spectrum = None coords = axes.format_coord(event.xdata, event.ydata) match = re.match('x=([-|0-9|\.]+).*y=([0-9|\:]+).*z=([-|0-9|\.]+)', coords) if match is not None and match.lastindex == 3: freq = float(match.group(1)) level = float(match.group(3)) text = "{}, {}".format( *format_precision(self.settings, freq, level)) else: spectrum = None if spectrum is not None and len(spectrum) > 0: x = min(spectrum.keys(), key=lambda freq: abs(freq - xpos)) if min(spectrum.keys(), key=float) <= xpos <= max(spectrum.keys(), key=float): y = spectrum[x] text = "{}, {}".format(*format_precision(self.settings, x, y)) else: text = format_precision(self.settings, xpos) markers = find_artists(self.figure, 'peak') markers.extend(find_artists(self.figure, 'peakThres')) hit = False for marker in markers: if isinstance(marker, Line2D): location = marker.get_path().vertices[0] markX, markY = axes.transData.transform(location) dist = abs(math.hypot(event.x - markX, event.y - markY)) if dist <= 5: if self.settings.display == Display.PLOT: tip = "{}, {}".format(*format_precision( self.settings, location[0], location[1])) else: tip = "{}".format( format_precision(self.settings, location[0])) self.toolTip.SetTip(tip) hit = True break self.toolTip.Enable(hit) self.status.set_info(text, level=None) def __on_size(self, event): ppi = wx.ScreenDC().GetPPI() size = [float(v) for v in self.canvas.GetSize()] width = size[0] / ppi[0] height = size[1] / ppi[1] self.figure.set_figwidth(width) self.figure.set_figheight(height) self.figure.set_dpi(ppi[0]) event.Skip() def __on_draw(self, _event): axes = self.plot.get_axes() if axes is not None: self.background = self.canvas.copy_from_bbox(axes.bbox) self.__draw_overlay() def __on_idle(self, _event): if self.doDraw and self.plot.get_plot_thread() is None: self.__hide_overlay() self.doDraw = False if os.name == 'nt': threading.Thread(target=self.__draw_canvas, name='Draw').start() else: self.__draw_canvas() def __on_timer(self, _event): self.timer.Stop() self.set_plot(None, None, None, None, self.annotate) def __draw_canvas(self): try: self.isDrawing = True self.canvas.draw() except wx.PyDeadObjectError: pass self.isDrawing = False wx.CallAfter(self.status.set_busy, False) def __draw_overlay(self): if self.background is not None: self.canvas.restore_region(self.background) self.__draw_select() self.draw_measure() axes = self.plot.get_axes() if axes is not None: self.canvas.blit(axes.bbox) def __draw_select(self): if self.selectStart is not None and self.selectEnd is not None: self.mouseSelect.draw(self.selectStart, self.selectEnd) def __hide_overlay(self): if self.plot is not None: self.plot.hide_measure() self.__hide_select() def __hide_select(self): if self.mouseSelect is not None: self.mouseSelect.hide() def create_plot(self): if self.plot is not None: self.plot.close() self.toolbar.set_auto(True) if self.settings.display == Display.PLOT: self.plot = Plotter(self.notify, self.figure, self.settings) elif self.settings.display == Display.SPECT: self.plot = Spectrogram(self.notify, self.figure, self.settings) elif self.settings.display == Display.SURFACE: self.plot = Plotter3d(self.notify, self.figure, self.settings) elif self.settings.display == Display.STATUS: self.plot = PlotterStatus(self.notify, self.figure, self.settings) elif self.settings.display == Display.TIMELINE: self.plot = PlotterTime(self.notify, self.figure, self.settings) elif self.settings.display == Display.PREVIEW: self.plot = PlotterPreview(self.notify, self.figure, self.settings) self.plot.set_window(self) self.__set_fonts() self.toolbar.set_plot(self.plot) self.toolbar.set_type(self.settings.display) self.measureTable.set_type(self.settings.display) self.set_plot_title() self.figure.subplots_adjust(top=0.85) self.redraw_plot() self.plot.scale_plot(True) self.mouseZoom = MouseZoom(self.toolbar, plot=self.plot, callbackHide=self.__hide_overlay) self.mouseSelect = MouseSelect(self.plot, self.on_select, self.on_selected) self.measureTable.show(self.settings.showMeasure) self.panel.SetFocus() def on_select(self): self.hide_measure() def on_selected(self, start, end): self.__enable_menu(True) self.selectStart = start self.selectEnd = end self.measureTable.set_selected(self.spectrum, start, end) def add_menu_clear_select(self, menu): self.menuClearSelect.append(menu) menu.Enable(False) def draw(self): self.doDraw = True def show_measure_table(self, show): self.measureTable.show(show) self.Layout() def set_plot(self, spectrum, isLimited, limit, extent, annotate=False): if spectrum is not None and extent is not None: if isLimited is not None and limit is not None: self.spectrum = copy.copy(spectrum) self.extent = extent self.annotate = annotate self.isLimited = isLimited self.limit = limit if self.plot.get_plot_thread() is None and not self.isDrawing: self.timer.Stop() self.measureTable.set_selected(self.spectrum, self.selectStart, self.selectEnd) if isLimited: self.spectrum = reduce_points(spectrum, limit) self.status.set_busy(True) self.plot.set_plot(self.spectrum, self.extent, annotate) if self.settings.display == Display.PREVIEW: self.status.set_busy(False) else: self.timer.Start(200, oneShot=True) def set_plot_title(self): if len(self.settings.devicesRtl) > 0: gain = self.settings.devicesRtl[self.settings.indexRtl].gain else: gain = 0 self.plot.set_title("Frequency Spectrogram\n{} - {} MHz," " gain = {}dB".format(self.settings.start, self.settings.stop, gain)) def redraw_plot(self): if self.spectrum is not None: self.set_plot(self.spectrum, self.settings.pointsLimit, self.settings.pointsMax, self.extent, self.settings.annotate) def set_grid(self, on): self.plot.set_grid(on) def set_selected(self, start, end): self.selectStart = start self.selectEnd = end self.__draw_select() def hide_toolbar(self, hide): self.toolbar.Show(not hide) def hide_measure(self): if self.plot is not None: self.plot.hide_measure() def draw_measure(self): if self.measure is not None and self.measure.is_valid(): self.plot.draw_measure(self.measure, self.show) def update_measure(self, measure=None, show=None): if not measure and not show: self.measureTable.update_measure() else: self.measure = measure self.show = show self.__draw_overlay() def get_figure(self): return self.figure def get_axes(self): return self.plot.get_axes() def get_canvas(self): return self.canvas def get_toolbar(self): return self.toolbar def get_mouse_select(self): return self.mouseSelect def scale_plot(self, force=False): self.plot.scale_plot(force) def clear_plots(self): self.plot.clear_plots() self.spectrum = None self.doDraw = True def clear_selection(self): self.measure = None self.measureTable.clear_measurement() self.selectStart = None self.selectEnd = None self.mouseSelect.clear() self.__enable_menu(False) def close(self): self.plot.close() close_modeless()