def _do_plot_boilerplate(kwargs, image=False): """ Used by various plotting functions. Checks/handles hold state, returns a Plot object for the plotting function to use. """ if "hold" in kwargs: hold(kwargs["hold"]) del kwargs["hold"] # Check for an active window; if none, open one. if len(session.windows) == 0: if image: win = session.new_window(is_image=True) activate(win) else: figure() cont = session.active_window.get_container() if not cont: cont = Plot(session.data) session.active_window.set_container(cont) existing_tools = [type(t) for t in (cont.tools + cont.overlays)] if not PanTool in existing_tools: cont.tools.append(PanTool(cont)) if not ZoomTool in existing_tools: cont.overlays.append(ZoomTool(cont, tool_mode="box", always_on=True, drag_button="right")) if not session.hold: cont.delplot(*list(cont.plots.keys())) return cont
def _create_plot_component(): # Create a scalar field to colormap xs = linspace(0, 10, 600) ys = linspace(0, 5, 600) x, y = meshgrid(xs,ys) z = exp(-(x**2+y**2)/100) # Create a plot data obect and give it this data pd = ArrayPlotData() pd.set_data("imagedata", z) # Create the plot plot = Plot(pd) img_plot = plot.img_plot("imagedata", xbounds=(0, 10), ybounds=(0, 5), colormap=jet)[0] # Tweak some of the plot properties plot.title = "My First Image Plot" plot.padding = 50 # Attach some tools to the plot plot.tools.append(PanTool(plot)) zoom = ZoomTool(component=img_plot, tool_mode="box", always_on=False) img_plot.overlays.append(zoom) return plot
def _create_plot_component(): # Create a fake dataset from which 2 dimensions will be displayed in a # scatter plot: x = np.random.uniform(0.0, 10.0, 50) y = np.random.uniform(0.0, 5.0, 50) data = pd.DataFrame({"x": x, "y": y, "dataset": np.random.choice(list("abcdefg"), 50)}) plot_data = ArrayPlotData(x=x, y=y) plot = Plot(plot_data) scatter = plot.plot(("x", "y"), type="scatter")[0] # Attach the inspector and its overlays inspector = DataframeScatterInspector( component=scatter, data=data ) scatter.tools.append(inspector) text_overlay = DataframeScatterOverlay(component=plot, inspector=inspector, bgcolor="black", alpha=0.6, text_color="white", border_color='none') plot.overlays.append(text_overlay) # Optional: add an overlay on the point to confirm what is hovered over # Note that this overlay magically knows about hovered points by # listening to renderer events rather than inspector events: point_overlay = ScatterInspectorOverlay(component=scatter, hover_color="red", hover_marker_size=6) scatter.overlays.append(point_overlay) return plot
def _create_plot_component(): # Create a scalar field to colormap xbounds = (-2 * pi, 2 * pi, 600) ybounds = (-1.5 * pi, 1.5 * pi, 300) xs = linspace(*xbounds) ys = linspace(*ybounds) x, y = meshgrid(xs, ys) z = sin(x) * y # Create a plot data obect and give it this data pd = ArrayPlotData() pd.set_data("imagedata", z) # Create the plot plot = Plot(pd) img_plot = plot.img_plot("imagedata", xbounds=xbounds[:2], ybounds=ybounds[:2], colormap=jet)[0] # Tweak some of the plot properties plot.title = "Image Plot with Lasso" plot.padding = 50 lasso_selection = LassoSelection(component=img_plot) lasso_selection.on_trait_change(lasso_updated, "disjoint_selections") lasso_overlay = LassoOverlay(lasso_selection=lasso_selection, component=img_plot) img_plot.tools.append(lasso_selection) img_plot.overlays.append(lasso_overlay) return plot
def updateplots(self): x = np.sort(np.random.random(100)) y = np.random.random(100) color = np.exp(-(x ** 2 + y ** 2)) # np.random.random(100) pd = ArrayPlotData() pd.set_data("index", x) pd.set_data("value", y) pd.set_data("color", color) # Create some line plots of some of the data plot = Plot(pd) # Create a scatter plot and get a reference to it (separate from the # Plot object) because we'll need it for the regression tool below. scatterplot = plot.plot( ("index", "value", "color"), type="cmap_scatter", color_mapper=reverse(Spectral), marker="square", fill_alpha=0.9, marker_size=6, bgcolor=QtGui.QColor(240, 240, 240), )[0] # Tweak some of the plot properties plot.padding = 50 # Attach some tools to the plot plot.tools.append(PanTool(plot, drag_button="right")) plot.overlays.append(ZoomTool(plot)) # Add the regression tool and overlay. These need to be added # directly to the scatterplot instance (and not the Plot instance). regression = RegressionLasso(scatterplot, selection_datasource=scatterplot.index) scatterplot.tools.append(regression) scatterplot.overlays.append(RegressionOverlay(scatterplot, lasso_selection=regression)) self.chaco_widget1.visualization.plot = plot self.chaco_widget2.visualization.plot = plot
def createWindow(widget): ''' Example on creating a new plot window in the main window MDI-Area ''' import plotWidget from PySide import QtGui from numpy import linspace from scipy.special import jn from chaco.api import ArrayPlotData, Plot window = widget.createNewWindow() container = plotWidget.plotContainer(window) plotWidget = plotWidget.PlotWidget(container) container.setPlotWidget(plotWidget) x = linspace(-2.0, 10.0, 100) pd = ArrayPlotData(index=x) for i in range(5): pd.set_data("y" + str(i), jn(i, x)) plot = Plot(pd, title=None, padding_left=60, padding_right=5, padding_top=5, padding_bottom=30, border_visible=True) plot.plot(("index", "y0", "y1", "y2"), name="j_n, n<3", color="red") plotWidget.setPlot(plot) layout = QtGui.QBoxLayout(QtGui.QBoxLayout.TopToBottom) layout.addWidget(container) window.setLayout(layout) window.show()
def _plot_default(self): plotter = Plot(data=self.data) main_plot = plotter.plot(['x','y'])[0] self.configure_plot(main_plot, xlabel='') plotter2 = Plot(data=self.data) zoom_plot = plotter2.plot(['x','y'])[0] self.configure_plot(zoom_plot) outer_container = VPlotContainer(padding=20, fill_padding=True, spacing=0, stack_order='top_to_bottom', bgcolor='lightgray', use_backbuffer=True) outer_container.add(main_plot) outer_container.add(zoom_plot) # FIXME: This is set to the windows bg color. Should get from the system. #outer_container.bgcolor = (236/255., 233/255., 216/255., 1.0) main_plot.controller = RangeSelection(main_plot) zoom_overlay = ZoomOverlay(source=main_plot, destination=zoom_plot) outer_container.overlays.append(zoom_overlay) return outer_container
def _plot_default(self): # Create a GridContainer to hold all of our plots: 2 rows, 4 columns: container = GridContainer(fill_padding=True, bgcolor="lightgray", use_backbuffer=True, shape=(2, 4)) arrangements = [('top left', 'h'), ('top right', 'h'), ('top left', 'v'), ('top right', 'v'), ('bottom left', 'h'), ('bottom right', 'h'), ('bottom left', 'v'), ('bottom right', 'v')] orientation_name = {'h': 'horizontal', 'v': 'vertical'} pd = ArrayPlotData(image=lena()) # Plot some bessel functions and add the plots to our container for origin, orientation in arrangements: plot = Plot(pd, default_origin=origin, orientation=orientation) plot.img_plot('image') # Attach some tools to the plot plot.tools.append(PanTool(plot)) zoom = ZoomTool(plot, tool_mode="box", always_on=False) plot.overlays.append(zoom) title = '{0}, {1}' plot.title = title.format(orientation_name[orientation], origin.replace(' ', '-')) # Add to the grid container container.add(plot) return container
def _create_plot_component(): # Create a random scattering of XY pairs x = random.uniform(0.0, 10.0, 50) y = random.uniform(0.0, 5.0, 50) pd = ArrayPlotData(x=x, y=y) plot = Plot(pd, border_visible=True, overlay_border=True) scatter = plot.plot(("x", "y"), type="scatter", color="lightblue")[0] # Tweak some of the plot properties plot.set(title="Scatter Inspector Demo", padding=50) # Attach some tools to the plot plot.tools.append(PanTool(plot)) plot.overlays.append(ZoomTool(plot)) # Attach the inspector and its overlay scatter.tools.append(ScatterInspector(scatter)) overlay = ScatterInspectorOverlay( scatter, hover_color="red", hover_marker_size=6, selection_marker_size=6, selection_color="yellow", selection_outline_color="purple", selection_line_width=3, ) scatter.overlays.append(overlay) return plot
def _sig_waveform_plot_default(self): plot = Plot(self.plot_data, padding=[75, 25, 25, 50], title='Signal Waveform') plot.plot(('time', 'sig_waveform'), color='black') plot.index_axis.title = 'Time (sec)' plot.value_axis.title = 'Signal (V)' return plot
def _sig_phase_plot_default(self): plot = Plot(self.plot_data, padding=[75, 25, 25, 50], title='Signal Spectrum') plot.plot(('frequency', 'sig_phase'), index_scale='log', color='black') plot.index_axis.title = 'Frequency (Hz)' plot.value_axis.title = 'Power (dB)' return plot
def _create_plot_component(): pd = ArrayPlotData(x=random(100), y=random(100)) # Create some line plots of some of the data plot = Plot(pd) # Create a scatter plot and get a reference to it (separate from the # Plot object) because we'll need it for the regression tool below. scatterplot = plot.plot(("x", "y"), color="blue", type="scatter")[0] # Tweak some of the plot properties plot.padding = 50 # Attach some tools to the plot plot.tools.append(PanTool(plot, drag_button="right")) plot.overlays.append(ZoomTool(plot)) # Add the regression tool and overlay. These need to be added # directly to the scatterplot instance (and not the Plot instance). regression = RegressionLasso(scatterplot, selection_datasource=scatterplot.index) scatterplot.tools.append(regression) scatterplot.overlays.append(RegressionOverlay(scatterplot, lasso_selection=regression)) return plot
def _interp_data_button_fired(self): x = [row.x for row in self.rows] y = [row.y for row in self.rows] f = interp1d(asarray(x), asarray(y)) y2 = Array print x, sorted(x) y2 = [f(i) for i in sorted(x)] print y2 plotdata = ArrayPlotData(x=x, y=y) plotdata2 = ArrayPlotData(y=y2) test_plot = Plot(plotdata) test_plot.plot(("x", "y"), type="scatter") test_plot.plot(("x", "y"), type="line") test_plot_2 = Plot(plotdata2) # test_plot_2.plot("y2", type="line") # changing type to line w)ill make the # plot a line plot! not recommended! """ test_plot = plot(x,y,"b-", bgcolor="white") test_plot.hold() test_plot = plot(x,y2,"g-") """ container = HPlotContainer(test_plot) # ,test_plot_2) self.aplot = container
def __init__(self): # Create some data x = np.random.random(N_POINTS) y = np.random.random(N_POINTS) color = np.exp(-(x**2 + y**2)) # Create a plot data object and give it this data data = ArrayPlotData(index=x, value=y, color=color) # Create the plot plot = Plot(data) plot.plot(("index", "value", "color"), type="cmap_scatter", color_mapper=jet) # Create the colorbar, handing in the appropriate range and colormap colormap = plot.color_mapper colorbar = ColorBar(index_mapper=LinearMapper(range=colormap.range), color_mapper=colormap, orientation='v', resizable='v', width=30, padding=20) colorbar.padding_top = plot.padding_top colorbar.padding_bottom = plot.padding_bottom # Create a container to position the plot and the colorbar side-by-side container = HPlotContainer(plot, colorbar) self.plot = container
class Viewer1D(Viewer): image = Array result = Array def _reconstruction_default(self): rows, cols = self.image.shape[:2] self.plot_data = ArrayPlotData(original=self.image[0], reconstruction=self.result[0]) aspect = cols/float(rows) old = Plot(self.plot_data) old.plot('original', ) old.title = 'Old' self.new = Plot(self.plot_data) self.new.plot('reconstruction') self.new.title = 'New' container = HPlotContainer(bgcolor='none') container.add(old) container.add(self.new) return container def update_plot(self): self.plot_data.set_data('reconstruction', self.result[0]) self.new.request_redraw()
def _hist2d_default(self): plot = Plot(self.hist2d_data, padding=(20, 0, 0, 40)) plot.img_plot("H", xbounds=self.xedges, ybounds=self.yedges, colormap=jet) plot.index_axis.title = "Voxel dist." plot.value_axis.title = "Root Square Error" # Create a colorbar colormap = plot.color_mapper colorbar = ColorBar(index_mapper=LinearMapper(range=colormap.range), color_mapper=colormap, plot=plot, orientation='v', resizable='v', width=20, padding=(20, 30, 0, 0)) colorbar.padding_top = plot.padding_top colorbar.padding_bottom = plot.padding_bottom # Create a container to position the plot and the colorbar side-by-side container = HPlotContainer(use_backbuffer=True, padding=0) container.add(colorbar) container.add(plot) container.bgcolor = "lightgray" return container
def _plot_default(self): # Create a GridContainer to hold all of our plots: 2 rows, 3 columns container = GridPlotContainer(shape=(2,3), spacing=(10,5), valign='top', bgcolor='lightgray') # Create x data x = linspace(-5, 15.0, 100) pd = ArrayPlotData(index = x) # Plot some Bessel functions and add the plots to our container for i in range(6): data_name = 'y{}'.format(i) pd.set_data(data_name, jn(i,x)) plot = Plot(pd) plot.plot(('index', data_name), color=COLOR_PALETTE[i], line_width=3.0) # Set each plot's aspect based on its position in the grid plot.set(height=((i % 3) + 1)*50, resizable='h') # Add to the grid container container.add(plot) return container
def plot_spectrum(self,x,y,field): for i in range(len(self.x_koords)): x_gap=abs(x-self.x_koords[i]) y_gap=abs(y-self.y_koords[i]) if x_gap <self.toleranz and y_gap<self.toleranz: spectrum=self.spectra[i] wavelength=self.ivCamera.create_wavelength_for_plotting() xm = [self.plotrangemarker,self.plotrangemarker] #for red line in plot ym = [0,16000] #self.plotrangey plotdata = ArrayPlotData(x=wavelength, y=spectrum,xm=xm,ym=ym) plot = Plot(plotdata) plot.plot(("x", "y"), type="line", color="blue") plot.x_axis.title="Wavelength [nm]" plot.y_axis.title="Counts" #catch error if apd counts not loaded try: apd_counts = str(self.apd_counts[i]) except: apd_counts = str("0") plot.title = 'spectrum of QD ' +str(self.x_koords[i])+' '+str(self.y_koords[i])+' with APD at '+str(apd_counts) plot.overlays.append(ZoomTool(component=plot,tool_mode="box", always_on=False)) # damit man im Plot zoomen kann plot.tools.append(PanTool(plot, constrain_key="shift")) # damit man mit der Maus den Plot verschieben kann if field=='current': self.plot_current=plot if self.plotsetalways: self._plotrangeset_fired() if field=='compare': self.plot_compare=plot if self.plotsetalways: self._plotrangeset_fired()
def _time_plot_default(self): time_plot = Plot(self.time_plot_data) time_plot.plot(('t', 'y')) time_plot.index_axis.title = "Time" time_plot.tools.append(PanTool(time_plot)) zoomtool = ZoomTool(time_plot, drag_button='right', always_on=True) time_plot.overlays.append(zoomtool) lines1 = CoordinateLineOverlay(component=time_plot, index_data=self.x1, value_data=self.y1, color=(0.75, 0.25, 0.25, 0.75), line_style='dash', line_width=1) time_plot.underlays.append(lines1) self.line_overlay1 = lines1 lines2 = CoordinateLineOverlay(component=time_plot, index_data=self.x2, value_data=self.y2, color=(0.2, 0.5, 1.0, 0.75), line_width=3) time_plot.underlays.append(lines2) self.line_overlay2 = lines2 return time_plot
def _create_corr_plot(self): plot = Plot(self.plotdata, padding=0) plot.padding_left = 25 plot.padding_bottom = 25 plot.tools.append(PanTool(plot)) plot.overlays.append(ZoomTool(plot)) self.corr_plot = plot
def _create_returns_plot(self): plot = Plot(self.plotdata) plot.legend.visible = True #FIXME: The legend move tool doesn't seem to quite work right now #plot.legend.tools.append(LegendTool(plot.legend)) plot.x_axis = None x_axis = PlotAxis(plot, orientation="bottom", tick_generator=ScalesTickGenerator(scale=CalendarScaleSystem())) plot.overlays.append(x_axis) plot.x_grid.tick_generator = x_axis.tick_generator for i, name in enumerate(self.plotdata.list_data()): if name == "times": continue renderer = plot.plot(("times", name), type="line", name=name, color=tuple(COLOR_PALETTE[i]))[0] # Tricky: need to set auto_handle_event on the RangeSelection # so that it passes left-clicks to the PanTool # FIXME: The range selection is still getting the initial left down renderer.tools.append(RangeSelection(renderer, left_button_selects = False, auto_handle_event = False)) plot.tools.append(PanTool(plot, drag_button="left", constrain=True, constrain_direction="x")) plot.overlays.append(ZoomTool(plot, tool_mode="range", max_zoom_out=1.0)) # Attach the range selection to the last renderer; any one will do self._range_selection_overlay = RangeSelectionOverlay(renderer, metadata_name="selections") renderer.overlays.append(self._range_selection_overlay) # Grab a reference to the Time axis datasource and add a listener to its # selections metadata self.times_ds = renderer.index self.times_ds.on_trait_change(self._selections_changed, 'metadata_changed') self.returns_plot = plot
def _ch_plot_default(self): x = 0.26 y = 0. h_cross_x = np.array([self.x_low, self.x_high]) h_cross_y = np.array([y, y]) v_cross_x = np.array([x, x]) v_cross_y = np.array([self.y_low, self.y_high]) cross_hair_data = ArrayPlotData(h_cross_x=h_cross_x, h_cross_y=h_cross_y, v_cross_x=v_cross_x, v_cross_y=v_cross_y) ch_plot = Plot(cross_hair_data) ch_plot.plot(("h_cross_x", "h_cross_y"), type="line", color="green",) ch_plot.plot(("v_cross_x", "v_cross_y"), type="line", color="green",) while len(ch_plot.underlays) > 0: ch_plot.underlays.pop(0) ch_plot.range2d = self.img_plot.range2d cross_hair_tool = CrossHairs(ch_plot) ch_plot.tools.append(cross_hair_tool) self.crosshair = cross_hair_tool self.on_trait_change(self.draw_cross_hairs, "crosshair.selected_x, crosshair.selected_y") self.on_trait_change(self.render_julia, "crosshair.selected_x, crosshair.selected_y") return ch_plot
def create_chaco_plot(parent, data, args, type=''): #x = linspace(-2.0, 10.0, 100) #pd = ArrayPlotData(index = x) #for i in range(5): # pd.set_data("y" + str(i), jn(i,x)) #if not type: # type = ['plot'] #else: # type = [type, 'plot'] # Create some line plots of some of the data plot = Plot(data, title="Line Plot", padding=50, border_visible=True) plot.legend.visible = True #plot_fn = getattr(plot, '_'.join(type)) if type: renderers = plot.plot(args, plot=type) else: renderers = plot.plot(args) #plot.plot(("index", "y3"), name="j_3", color="blue") # Attach some tools to the plot plot.tools.append(PanTool(plot)) zoom = ZoomTool(component=plot, tool_mode="box", always_on=False) plot.overlays.append(zoom) plot.tools.append(TraitsTool(component=plot)) # This Window object bridges the Enable and Qt4 worlds, and handles events # and drawing. We can create whatever hierarchy of nested containers we # want, as long as the top-level item gets set as the .component attribute # of a Window. return Window(parent, -1, component = plot)
def __init__(self): # The delegates views don't work unless we caller the superclass __init__ super(CursorTest, self).__init__() container = HPlotContainer(padding=0, spacing=20) self.plot = container # a subcontainer for the first plot. # I'm not sure why this is required. Without it, the layout doesn't work right. subcontainer = OverlayPlotContainer(padding=40) container.add(subcontainer) # make some data index = numpy.linspace(-10, 10, 512) value = numpy.sin(index) # create a LinePlot instance and add it to the subcontainer line = create_line_plot([index, value], add_grid=True, add_axis=True, index_sort="ascending", orientation="h") subcontainer.add(line) # here's our first cursor. csr = CursorTool(line, drag_button="left", color="blue") self.cursor1 = csr # and set it's initial position (in data-space units) csr.current_position = 0.0, 0.0 # this is a rendered component so it goes in the overlays list line.overlays.append(csr) # some other standard tools line.tools.append(PanTool(line, drag_button="right")) line.overlays.append(ZoomTool(line)) # make some 2D data for a colourmap plot xy_range = (-5, 5) x = numpy.linspace(xy_range[0], xy_range[1], 100) y = numpy.linspace(xy_range[0], xy_range[1], 100) X, Y = numpy.meshgrid(x, y) Z = numpy.sin(X) * numpy.arctan2(Y, X) # easiest way to get a CMapImagePlot is to use the Plot class ds = ArrayPlotData() ds.set_data("img", Z) img = Plot(ds, padding=40) cmapImgPlot = img.img_plot("img", xbounds=xy_range, ybounds=xy_range, colormap=jet)[0] container.add(img) # now make another cursor csr2 = CursorTool(cmapImgPlot, drag_button="left", color="white", line_width=2.0) self.cursor2 = csr2 csr2.current_position = 1.0, 1.5 cmapImgPlot.overlays.append(csr2) # add some standard tools. Note, I'm assigning the PanTool to the # right mouse-button to avoid conflicting with the cursors cmapImgPlot.tools.append(PanTool(cmapImgPlot, drag_button="right")) cmapImgPlot.overlays.append(ZoomTool(cmapImgPlot))
class PlotExample(HasTraits): plot = Instance(Plot) traits_view = View(UItem('plot', editor=ComponentEditor()), width=400, height=400, resizable=True, ) def __init__(self, index, series_a, series_b, series_c, **kw): super(PlotExample, self).__init__(**kw) plot_data = ArrayPlotData(index=index) plot_data.set_data('series_a', series_a) plot_data.set_data('series_b', series_b) plot_data.set_data('series_c', series_c) self.plot = Plot(plot_data) self.plot.plot(('index', 'series_a'), type='bar', bar_width=0.8, color='auto') self.plot.plot(('index', 'series_b'), type='bar', bar_width=0.8, color='auto') self.plot.plot(('index', 'series_c'), type='bar', bar_width=0.8, color='auto') # set the plot's value range to 0, otherwise it may pad too much self.plot.value_range.low = 0 # replace the index values with some nicer labels label_axis = LabelAxis(self.plot, orientation='bottom', title='Months', positions = list(range(1, 10)), labels = ['jan', 'feb', 'march', 'april', 'may'], small_haxis_style=True) self.plot.underlays.remove(self.plot.index_axis) self.plot.index_axis = label_axis self.plot.underlays.append(label_axis)
def _plot_default(self): data = ArrayPlotData(x=self.model.x, y=self.model.y) plot = Plot(data) plot.plot(('x', 'y'), style='line', color='green') plot.value_range.set_bounds(-self.model.a, self.model.a) plot.title = "a * exp(-b*x) * cos(omega*x + phase)" return plot
def _create_plot_component():# Create a scalar field to colormap xbounds = (-2*pi, 2*pi, 600) ybounds = (-1.5*pi, 1.5*pi, 300) xs = linspace(*xbounds) ys = linspace(*ybounds) x, y = meshgrid(xs,ys) z = sin(x)*y # Create a plot data obect and give it this data pd = ArrayPlotData() pd.set_data("imagedata", z) # Create the plot plot = Plot(pd) img_plot = plot.img_plot("imagedata", xbounds = xbounds[:2], ybounds = ybounds[:2], colormap=jet)[0] # Tweak some of the plot properties plot.title = "My First Image Plot" plot.padding = 50 # Attach some tools to the plot plot.tools.append(PanTool(plot)) zoom = ZoomTool(component=plot, tool_mode="box", always_on=False) plot.overlays.append(zoom) imgtool = ImageInspectorTool(img_plot) img_plot.tools.append(imgtool) overlay = ImageInspectorOverlay(component=img_plot, image_inspector=imgtool, bgcolor="white", border_visible=True) img_plot.overlays.append(overlay) return plot
def _create_plot_component(): # Create some RGBA image data image = zeros((200,400,4), dtype=uint8) image[:,0:40,0] += 255 # Vertical red stripe image[0:25,:,1] += 255 # Horizontal green stripe; also yellow square image[-80:,-160:,2] += 255 # Blue square image[:,:,3] = 255 # Create a plot data obect and give it this data pd = ArrayPlotData() pd.set_data("imagedata", image) # Create the plot plot = Plot(pd, default_origin="top left") plot.x_axis.orientation = "top" img_plot = plot.img_plot("imagedata")[0] # Tweak some of the plot properties plot.bgcolor = "white" # Attach some tools to the plot plot.tools.append(PanTool(plot, constrain_key="shift")) plot.overlays.append(ZoomTool(component=plot, tool_mode="box", always_on=False)) imgtool = ImageInspectorTool(img_plot) img_plot.tools.append(imgtool) plot.overlays.append(ImageInspectorOverlay(component=img_plot, image_inspector=imgtool)) return plot
def _create_plot_component(obj): # Spectrogram plot obj.data = fr.getDataSets(".chi") frequencies = obj.data[0][0] index = ArrayDataSource(data=frequencies) values = [obj.data[i][1] for i in xrange(len(obj.data))] print len(obj.data[1][1]) print len(obj.data) p = WaterfallRenderer( index=index, values=values, index_mapper=LinearMapper(range=DataRange1D(low=0, high=SPECTROGRAM_LENGTH)), value_mapper=LinearMapper(range=DataRange1D(low=0, high=SPECTROGRAM_LENGTH)), x2_mapper=LinearMapper(low_pos=0, high_pos=100, range=DataRange1D(low=10.0, high=101.0)), y2_mapper=LinearMapper(low_pos=0, high_pos=100, range=DataRange1D(low=0, high=600000)), ) spectrogram_plot = p obj.spectrogram_plot = p dummy = Plot() dummy.padding = 50 dummy.index_axis.mapper.range = p.index_mapper.range dummy.index_axis.title = "Frequency (hz)" dummy.add(p) c2 = VPlotContainer() c2.add(dummy) return c2
def update_show_curve(self): plotdata = ArrayPlotData(x=self.ct_hu, y=self.re_electronic_density) plot = Plot(plotdata) plot.plot(("x", "y"), type="line", color="blue") plot.title = self.name self.plot = plot
class SolutionView(HasTraits): python_console_cmds = Dict() lats = List() lngs = List() alts = List() table = List() dops_table = List() pos_table = List() vel_table = List() plot = Instance(Plot) plot_data = Instance(ArrayPlotData) running = Bool(True) position_centered = Bool(False) clear_button = SVGButton(label='', tooltip='Clear', filename=os.path.join(os.path.dirname(__file__), 'images', 'iconic', 'x.svg'), width=16, height=16) zoomall_button = SVGButton(label='', tooltip='Zoom All', filename=os.path.join(os.path.dirname(__file__), 'images', 'iconic', 'fullscreen.svg'), width=16, height=16) center_button = SVGButton(label='', tooltip='Center on Solution', toggle=True, filename=os.path.join(os.path.dirname(__file__), 'images', 'iconic', 'target.svg'), width=16, height=16) paused_button = SVGButton( label='', tooltip='Pause', toggle_tooltip='Run', toggle=True, filename=os.path.join(os.path.dirname(__file__), 'images', 'iconic', 'pause.svg'), toggle_filename=os.path.join(os.path.dirname(__file__), 'images', 'iconic', 'play.svg'), width=16, height=16) traits_view = View( HSplit( Item('table', style='readonly', editor=TabularEditor(adapter=SimpleAdapter()), show_label=False, width=0.3), VGroup( HGroup( Item('paused_button', show_label=False), Item('clear_button', show_label=False), Item('zoomall_button', show_label=False), Item('center_button', show_label=False), ), Item( 'plot', show_label=False, editor=ComponentEditor(bgcolor=(0.8, 0.8, 0.8)), )))) def _zoomall_button_fired(self): self.plot.index_range.low_setting = 'auto' self.plot.index_range.high_setting = 'auto' self.plot.value_range.low_setting = 'auto' self.plot.value_range.high_setting = 'auto' def _center_button_fired(self): self.position_centered = not self.position_centered def _paused_button_fired(self): self.running = not self.running def _clear_button_fired(self): self.lats = [] self.lngs = [] self.alts = [] self.plot_data.set_data('lat', []) self.plot_data.set_data('lng', []) self.plot_data.set_data('alt', []) self.plot_data.set_data('t', []) def _pos_llh_callback(self, data): # Updating an ArrayPlotData isn't thread safe (see chaco issue #9), so # actually perform the update in the UI thread. if self.running: GUI.invoke_later(self.pos_llh_callback, data) def update_table(self): self._table_list = self.table.items() def pos_llh_callback(self, data): soln = sbp_messages.PosLLH(data) self.pos_table = [] if self.log_file is None: self.log_file = open( time.strftime("position_log_%Y%m%d-%H%M%S.csv"), 'w') tow = soln.tow * 1e-3 if self.nsec is not None: tow += self.nsec * 1e-9 if self.week is not None: t = datetime.datetime(1980, 1, 6) + \ datetime.timedelta(weeks=self.week) + \ datetime.timedelta(seconds=tow) self.pos_table.append(('GPS Time', t)) self.pos_table.append(('GPS Week', str(self.week))) self.log_file.write( '%s,%.10f,%.10f,%.4f,%d\n' % (str(t), soln.lat, soln.lon, soln.height, soln.n_sats)) self.log_file.flush() self.pos_table.append(('GPS ToW', tow)) self.pos_table.append(('Num. sats', soln.n_sats)) self.pos_table.append(('Lat', soln.lat)) self.pos_table.append(('Lng', soln.lon)) self.pos_table.append(('Alt', soln.height)) self.lats.append(soln.lat) self.lngs.append(soln.lon) self.alts.append(soln.height) self.lats = self.lats[-1000:] self.lngs = self.lngs[-1000:] self.alts = self.alts[-1000:] self.plot_data.set_data('lat', self.lats) self.plot_data.set_data('lng', self.lngs) self.plot_data.set_data('alt', self.alts) t = range(len(self.lats)) self.plot_data.set_data('t', t) self.table = self.pos_table + self.vel_table + self.dops_table if self.position_centered: d = (self.plot.index_range.high - self.plot.index_range.low) / 2. self.plot.index_range.set_bounds(soln.pos_llh[0] - d, soln.pos_llh[0] + d) d = (self.plot.value_range.high - self.plot.value_range.low) / 2. self.plot.value_range.set_bounds(soln.pos_llh[1] - d, soln.pos_llh[1] + d) def dops_callback(self, data): dops = sbp_messages.Dops(data) self.dops_table = [('PDOP', '%.1f' % (dops.pdop * 0.01)), ('GDOP', '%.1f' % (dops.gdop * 0.01)), ('TDOP', '%.1f' % (dops.tdop * 0.01)), ('HDOP', '%.1f' % (dops.hdop * 0.01)), ('VDOP', '%.1f' % (dops.vdop * 0.01))] self.table = self.pos_table + self.vel_table + self.dops_table def vel_ned_callback(self, data): vel_ned = sbp_messages.VelNED(data) if self.vel_log_file is None: self.vel_log_file = open( time.strftime("velocity_log_%Y%m%d-%H%M%S.csv"), 'w') tow = vel_ned.tow * 1e-3 if self.nsec is not None: tow += self.nsec * 1e-9 if self.week is not None: t = datetime.datetime(1980, 1, 6) + \ datetime.timedelta(weeks=self.week) + \ datetime.timedelta(seconds=tow) self.vel_log_file.write( '%s,%.6f,%.6f,%.6f,%.6f,%d\n' % (str(t), vel_ned.n * 1e-3, vel_ned.e * 1e-3, vel_ned.d * 1e-3, math.sqrt(vel_ned.n * vel_ned.n + vel_ned.e * vel_ned.e) * 1e-3, vel_ned.n_sats)) self.vel_log_file.flush() self.vel_table = [ ('Vel. N', '% 8.4f' % (vel_ned.n * 1e-3)), ('Vel. E', '% 8.4f' % (vel_ned.e * 1e-3)), ('Vel. D', '% 8.4f' % (vel_ned.d * 1e-3)), ] self.table = self.pos_table + self.vel_table + self.dops_table def gps_time_callback(self, data): self.week = sbp_messages.GPSTime(data).wn self.nsec = sbp_messages.GPSTime(data).ns def __init__(self, link): super(SolutionView, self).__init__() self.log_file = None self.vel_log_file = None self.plot_data = ArrayPlotData(lat=[0.0], lng=[0.0], alt=[0.0], t=[0.0], ref_lat=[0.0], ref_lng=[0.0], region_lat=[0.0], region_lng=[0.0]) self.plot = Plot(self.plot_data) self.plot.plot(('lng', 'lat'), type='line', name='line', color=(0, 0, 0, 0.1)) self.plot.plot(('lng', 'lat'), type='scatter', name='points', color='blue', marker='dot', line_width=0.0, marker_size=1.0) self.plot.index_axis.tick_label_position = 'inside' self.plot.index_axis.tick_label_color = 'gray' self.plot.index_axis.tick_color = 'gray' self.plot.value_axis.tick_label_position = 'inside' self.plot.value_axis.tick_label_color = 'gray' self.plot.value_axis.tick_color = 'gray' self.plot.padding = (0, 1, 0, 1) self.plot.tools.append(PanTool(self.plot)) zt = ZoomTool(self.plot, zoom_factor=1.1, tool_mode="box", always_on=False) self.plot.overlays.append(zt) self.link = link self.link.add_callback(sbp_messages.SBP_POS_LLH, self._pos_llh_callback) self.link.add_callback(sbp_messages.SBP_VEL_NED, self.vel_ned_callback) self.link.add_callback(sbp_messages.SBP_DOPS, self.dops_callback) self.link.add_callback(sbp_messages.SBP_GPS_TIME, self.gps_time_callback) self.week = None self.nsec = 0 self.python_console_cmds = {'solution': self}
def create_plot(self): # Create the mapper, etc self._image_index = GridDataSource(array([]), array([]), sort_order=("ascending", "ascending")) image_index_range = DataRange2D(self._image_index) self._image_index.on_trait_change(self._metadata_changed, "metadata_changed") self._image_value = ImageData(data=array([]), value_depth=1) image_value_range = DataRange1D(self._image_value) # Create the contour plots self.polyplot = ContourPolyPlot(index=self._image_index, value=self._image_value, index_mapper=GridMapper(range= image_index_range), color_mapper=\ self._cmap(image_value_range), levels=self.num_levels) self.lineplot = ContourLinePlot( index=self._image_index, value=self._image_value, index_mapper=GridMapper(range=self.polyplot.index_mapper.range), levels=self.num_levels) # Add a left axis to the plot left = PlotAxis(orientation='left', title="y", mapper=self.polyplot.index_mapper._ymapper, component=self.polyplot) self.polyplot.overlays.append(left) # Add a bottom axis to the plot bottom = PlotAxis(orientation='bottom', title="x", mapper=self.polyplot.index_mapper._xmapper, component=self.polyplot) self.polyplot.overlays.append(bottom) # Add some tools to the plot self.polyplot.tools.append( PanTool(self.polyplot, constrain_key="shift")) self.polyplot.overlays.append( ZoomTool(component=self.polyplot, tool_mode="box", always_on=False)) self.polyplot.overlays.append( LineInspector(component=self.polyplot, axis='index_x', inspect_mode="indexed", write_metadata=True, is_listener=True, color="white")) self.polyplot.overlays.append( LineInspector(component=self.polyplot, axis='index_y', inspect_mode="indexed", write_metadata=True, color="white", is_listener=True)) # Add these two plots to one container contour_container = OverlayPlotContainer(padding=20, use_backbuffer=True, unified_draw=True) contour_container.add(self.polyplot) contour_container.add(self.lineplot) # Create a colorbar cbar_index_mapper = LinearMapper(range=image_value_range) self.colorbar = ColorBar(index_mapper=cbar_index_mapper, plot=self.polyplot, padding_top=self.polyplot.padding_top, padding_bottom=self.polyplot.padding_bottom, padding_right=40, resizable='v', width=30) self.pd = ArrayPlotData(line_index=array([]), line_value=array([]), scatter_index=array([]), scatter_value=array([]), scatter_color=array([])) self.cross_plot = Plot(self.pd, resizable="h") self.cross_plot.height = 100 self.cross_plot.padding = 20 self.cross_plot.plot(("line_index", "line_value"), line_style="dot") self.cross_plot.plot( ("scatter_index", "scatter_value", "scatter_color"), type="cmap_scatter", name="dot", color_mapper=self._cmap(image_value_range), marker="circle", marker_size=8) self.cross_plot.index_range = self.polyplot.index_range.x_range self.pd.set_data("line_index2", array([])) self.pd.set_data("line_value2", array([])) self.pd.set_data("scatter_index2", array([])) self.pd.set_data("scatter_value2", array([])) self.pd.set_data("scatter_color2", array([])) self.cross_plot2 = Plot(self.pd, width=140, orientation="v", resizable="v", padding=20, padding_bottom=160) self.cross_plot2.plot(("line_index2", "line_value2"), line_style="dot") self.cross_plot2.plot( ("scatter_index2", "scatter_value2", "scatter_color2"), type="cmap_scatter", name="dot", color_mapper=self._cmap(image_value_range), marker="circle", marker_size=8) self.cross_plot2.index_range = self.polyplot.index_range.y_range # Create a container and add components self.container = HPlotContainer(padding=40, fill_padding=True, bgcolor="white", use_backbuffer=False) inner_cont = VPlotContainer(padding=0, use_backbuffer=True) inner_cont.add(self.cross_plot) inner_cont.add(contour_container) self.container.add(self.colorbar) self.container.add(inner_cont) self.container.add(self.cross_plot2)
class PlotUI(HasTraits): # container for all plots container = Instance(HPlotContainer) # Plot components within this container: polyplot = Instance(ContourPolyPlot) lineplot = Instance(ContourLinePlot) cross_plot = Instance(Plot) cross_plot2 = Instance(Plot) colorbar = Instance(ColorBar) # plot data pd = Instance(ArrayPlotData) # view options num_levels = Int(15) colormap = Enum(colormaps) #Traits view definitions: traits_view = View(Group( UItem('container', editor=ComponentEditor(size=(800, 600)))), resizable=True) plot_edit_view = View(Group(Item('num_levels'), Item('colormap')), buttons=["OK", "Cancel"]) #--------------------------------------------------------------------------- # Private Traits #--------------------------------------------------------------------------- _image_index = Instance(GridDataSource) _image_value = Instance(ImageData) _cmap = Trait(default_colormaps.viridis, Callable) #--------------------------------------------------------------------------- # Public View interface #--------------------------------------------------------------------------- def __init__(self, *args, **kwargs): super(PlotUI, self).__init__(*args, **kwargs) # FIXME: 'with' wrapping is temporary fix for infinite range in initial # color map, which can cause a distracting warning print. This 'with' # wrapping should be unnecessary after fix in color_mapper.py. with errstate(invalid='ignore'): self.create_plot() def create_plot(self): # Create the mapper, etc self._image_index = GridDataSource(array([]), array([]), sort_order=("ascending", "ascending")) image_index_range = DataRange2D(self._image_index) self._image_index.on_trait_change(self._metadata_changed, "metadata_changed") self._image_value = ImageData(data=array([]), value_depth=1) image_value_range = DataRange1D(self._image_value) # Create the contour plots self.polyplot = ContourPolyPlot(index=self._image_index, value=self._image_value, index_mapper=GridMapper(range= image_index_range), color_mapper=\ self._cmap(image_value_range), levels=self.num_levels) self.lineplot = ContourLinePlot( index=self._image_index, value=self._image_value, index_mapper=GridMapper(range=self.polyplot.index_mapper.range), levels=self.num_levels) # Add a left axis to the plot left = PlotAxis(orientation='left', title="y", mapper=self.polyplot.index_mapper._ymapper, component=self.polyplot) self.polyplot.overlays.append(left) # Add a bottom axis to the plot bottom = PlotAxis(orientation='bottom', title="x", mapper=self.polyplot.index_mapper._xmapper, component=self.polyplot) self.polyplot.overlays.append(bottom) # Add some tools to the plot self.polyplot.tools.append( PanTool(self.polyplot, constrain_key="shift")) self.polyplot.overlays.append( ZoomTool(component=self.polyplot, tool_mode="box", always_on=False)) self.polyplot.overlays.append( LineInspector(component=self.polyplot, axis='index_x', inspect_mode="indexed", write_metadata=True, is_listener=True, color="white")) self.polyplot.overlays.append( LineInspector(component=self.polyplot, axis='index_y', inspect_mode="indexed", write_metadata=True, color="white", is_listener=True)) # Add these two plots to one container contour_container = OverlayPlotContainer(padding=20, use_backbuffer=True, unified_draw=True) contour_container.add(self.polyplot) contour_container.add(self.lineplot) # Create a colorbar cbar_index_mapper = LinearMapper(range=image_value_range) self.colorbar = ColorBar(index_mapper=cbar_index_mapper, plot=self.polyplot, padding_top=self.polyplot.padding_top, padding_bottom=self.polyplot.padding_bottom, padding_right=40, resizable='v', width=30) self.pd = ArrayPlotData(line_index=array([]), line_value=array([]), scatter_index=array([]), scatter_value=array([]), scatter_color=array([])) self.cross_plot = Plot(self.pd, resizable="h") self.cross_plot.height = 100 self.cross_plot.padding = 20 self.cross_plot.plot(("line_index", "line_value"), line_style="dot") self.cross_plot.plot( ("scatter_index", "scatter_value", "scatter_color"), type="cmap_scatter", name="dot", color_mapper=self._cmap(image_value_range), marker="circle", marker_size=8) self.cross_plot.index_range = self.polyplot.index_range.x_range self.pd.set_data("line_index2", array([])) self.pd.set_data("line_value2", array([])) self.pd.set_data("scatter_index2", array([])) self.pd.set_data("scatter_value2", array([])) self.pd.set_data("scatter_color2", array([])) self.cross_plot2 = Plot(self.pd, width=140, orientation="v", resizable="v", padding=20, padding_bottom=160) self.cross_plot2.plot(("line_index2", "line_value2"), line_style="dot") self.cross_plot2.plot( ("scatter_index2", "scatter_value2", "scatter_color2"), type="cmap_scatter", name="dot", color_mapper=self._cmap(image_value_range), marker="circle", marker_size=8) self.cross_plot2.index_range = self.polyplot.index_range.y_range # Create a container and add components self.container = HPlotContainer(padding=40, fill_padding=True, bgcolor="white", use_backbuffer=False) inner_cont = VPlotContainer(padding=0, use_backbuffer=True) inner_cont.add(self.cross_plot) inner_cont.add(contour_container) self.container.add(self.colorbar) self.container.add(inner_cont) self.container.add(self.cross_plot2) def update(self, model): self.minz = model.minz self.maxz = model.maxz self.colorbar.index_mapper.range.low = self.minz self.colorbar.index_mapper.range.high = self.maxz self._image_index.set_data(model.xs, model.ys) self._image_value.data = model.zs self.pd.update_data(line_index=model.xs, line_index2=model.ys) self.container.invalidate_draw() self.container.request_redraw() #--------------------------------------------------------------------------- # Event handlers #--------------------------------------------------------------------------- def _metadata_changed(self, old, new): """ This function takes out a cross section from the image data, based on the line inspector selections, and updates the line and scatter plots.""" self.cross_plot.value_range.low = self.minz self.cross_plot.value_range.high = self.maxz self.cross_plot2.value_range.low = self.minz self.cross_plot2.value_range.high = self.maxz if "selections" in self._image_index.metadata: x_ndx, y_ndx = self._image_index.metadata["selections"] if y_ndx and x_ndx: xdata, ydata = self._image_index.get_data() xdata, ydata = xdata.get_data(), ydata.get_data() self.pd.update_data( line_value=self._image_value.data[y_ndx, :], line_value2=self._image_value.data[:, x_ndx], scatter_index=array([xdata[x_ndx]]), scatter_index2=array([ydata[y_ndx]]), scatter_value=array([self._image_value.data[y_ndx, x_ndx]]), scatter_value2=array( [self._image_value.data[y_ndx, x_ndx]]), scatter_color=array([self._image_value.data[y_ndx, x_ndx]]), scatter_color2=array( [self._image_value.data[y_ndx, x_ndx]])) else: self.pd.update_data({ "scatter_value": array([]), "scatter_value2": array([]), "line_value": array([]), "line_value2": array([]) }) def _colormap_changed(self): self._cmap = default_colormaps.color_map_name_dict[self.colormap] if self.polyplot is not None: value_range = self.polyplot.color_mapper.range self.polyplot.color_mapper = self._cmap(value_range) value_range = self.cross_plot.color_mapper.range self.cross_plot.color_mapper = self._cmap(value_range) # FIXME: change when we decide how best to update plots using # the shared colormap in plot object self.cross_plot.plots["dot"][0].color_mapper = self._cmap( value_range) self.cross_plot2.plots["dot"][0].color_mapper = self._cmap( value_range) self.container.request_redraw() def _num_levels_changed(self): if self.num_levels > 3: self.polyplot.levels = self.num_levels self.lineplot.levels = self.num_levels
def _create_window(self): self.model = model = Model() cmap = jet self._update_model(cmap) # Create the plot self.plotdata = ArrayPlotData() self._update_images() # Center Plot centerplot = Plot(self.plotdata, padding=0) imgplot = centerplot.img_plot("xy", xbounds=(model.min_x, model.max_x), ybounds=(model.min_y, model.max_y), colormap=cmap)[0] self._add_plot_tools(imgplot, "xy") self.center = imgplot # Right Plot rightplot = Plot(self.plotdata, width=150, resizable="v", padding=0) rightplot.value_range = centerplot.value_range imgplot = rightplot.img_plot("yz", xbounds=(model.min_z, model.max_z), ybounds=(model.min_y, model.max_y), colormap=cmap)[0] self._add_plot_tools(imgplot, "yz") self.right = imgplot # Bottom Plot. Seismic plot axis1 (depth) down into earth # i.e. z is depth, to altitude. bottomplot = Plot(self.plotdata, height=150, resizable="h", padding=0, origin="top left") bottomplot.index_range = centerplot.index_range imgplot = bottomplot.img_plot("xz", xbounds=(model.min_x, model.max_x), ybounds=(model.min_z, model.max_z), colormap=cmap)[0] self._add_plot_tools(imgplot, "xz") self.bottom = imgplot # Create Container and add all Plots container = GridPlotContainer(padding=20, fill_padding=True, bgcolor="white", use_backbuffer=True, shape=(2,2), spacing=(20,20)) container.add(centerplot) container.add(rightplot) container.add(bottomplot) self.container = container return Window(self, -1, component=container)
def create_plot(self, parent): plot = Plot(self.plotdata, padding=50, border_visible=True) plot.plot(("x", "y"), name="data plot", color="green") return Window(parent, -1, component=plot)
def make_plots(self, n_dfe_taps): """ Create the plots used by the PyBERT GUI.""" post_chnl_str = "Channel" post_tx_str = "Channel + Tx Preemphasis" post_ctle_str = "Channel + Tx Preemphasis + CTLE (+ AMI DFE)" post_dfe_str = "Channel + Tx Preemphasis + CTLE (+ AMI DFE) + PyBERT DFE" plotdata = self.plotdata # - DFE tab plot2 = Plot(plotdata, padding_left=75) plot2.plot(("t_ns", "ui_ests"), type="line", color="blue") plot2.title = "CDR Adaptation" plot2.index_axis.title = "Time (ns)" plot2.value_axis.title = "UI (ps)" plot9 = Plot(plotdata, auto_colors=["red", "orange", "yellow", "green", "blue", "purple"], padding_left=75,) for i in range(n_dfe_taps): plot9.plot( ("tap_weight_index", "tap%d_weights" % (i + 1)), type="line", color="auto", name="tap%d" % (i + 1), ) plot9.title = "DFE Adaptation" plot9.tools.append(PanTool(plot9, constrain=True, constrain_key=None, constrain_direction="x")) zoom9 = ZoomTool(plot9, tool_mode="range", axis="index", always_on=False) plot9.overlays.append(zoom9) plot9.legend.visible = True plot9.legend.align = "ul" plot_clk_per_hist = Plot(plotdata, padding_left=75) plot_clk_per_hist.plot(("clk_per_hist_bins", "clk_per_hist_vals"), type="line", color="blue") plot_clk_per_hist.title = "CDR Clock Period Histogram" plot_clk_per_hist.index_axis.title = "Clock Period (ps)" plot_clk_per_hist.value_axis.title = "Bin Count" plot_clk_per_spec = Plot(plotdata, padding_left=75) plot_clk_per_spec.plot(("clk_freqs", "clk_spec"), type="line", color="blue") plot_clk_per_spec.title = "CDR Clock Period Spectrum" plot_clk_per_spec.index_axis.title = "Frequency (bit rate)" plot_clk_per_spec.value_axis.title = "|H(f)| (dB mean)" plot_clk_per_spec.value_range.low_setting = -10 zoom_clk_per_spec = ZoomTool(plot_clk_per_spec, tool_mode="range", axis="index", always_on=False) plot_clk_per_spec.overlays.append(zoom_clk_per_spec) container_dfe = GridPlotContainer(shape=(2, 2)) container_dfe.add(plot2) container_dfe.add(plot9) container_dfe.add(plot_clk_per_hist) container_dfe.add(plot_clk_per_spec) self.plots_dfe = container_dfe self._dfe_plot = plot9 # - EQ Tune tab plot_h_tune = Plot(plotdata, padding_left=75) plot_h_tune.plot(("t_ns_chnl", "ctle_out_h_tune"), type="line", color="blue") plot_h_tune.plot(("t_ns_chnl", "clocks_tune"), type="line", color="gray") plot_h_tune.title = "Channel + Tx Preemphasis + CTLE (+ AMI DFE) + Ideal DFE" plot_h_tune.index_axis.title = "Time (ns)" plot_h_tune.y_axis.title = "Pulse Response (V)" zoom_tune = ZoomTool(plot_h_tune, tool_mode="range", axis="index", always_on=False) plot_h_tune.overlays.append(zoom_tune) self.plot_h_tune = plot_h_tune # - Impulse Responses tab plot_h_chnl = Plot(plotdata, padding_left=75) plot_h_chnl.plot(("t_ns_chnl", "chnl_h"), type="line", color="blue", name="Incremental") plot_h_chnl.title = post_chnl_str plot_h_chnl.index_axis.title = "Time (ns)" plot_h_chnl.y_axis.title = "Impulse Response (V/ns)" plot_h_chnl.legend.visible = True plot_h_chnl.legend.align = "ur" zoom_h = ZoomTool(plot_h_chnl, tool_mode="range", axis="index", always_on=False) plot_h_chnl.overlays.append(zoom_h) plot_h_tx = Plot(plotdata, padding_left=75) plot_h_tx.plot(("t_ns_chnl", "tx_out_h"), type="line", color="red", name="Cumulative") plot_h_tx.title = post_tx_str plot_h_tx.index_axis.title = "Time (ns)" plot_h_tx.y_axis.title = "Impulse Response (V/ns)" plot_h_tx.legend.visible = True plot_h_tx.legend.align = "ur" plot_h_tx.index_range = plot_h_chnl.index_range # Zoom x-axes in tandem. plot_h_ctle = Plot(plotdata, padding_left=75) plot_h_ctle.plot(("t_ns_chnl", "ctle_out_h"), type="line", color="red", name="Cumulative") plot_h_ctle.title = post_ctle_str plot_h_ctle.index_axis.title = "Time (ns)" plot_h_ctle.y_axis.title = "Impulse Response (V/ns)" plot_h_ctle.legend.visible = True plot_h_ctle.legend.align = "ur" plot_h_ctle.index_range = plot_h_chnl.index_range # Zoom x-axes in tandem. plot_h_dfe = Plot(plotdata, padding_left=75) plot_h_dfe.plot(("t_ns_chnl", "dfe_out_h"), type="line", color="red", name="Cumulative") plot_h_dfe.title = post_dfe_str plot_h_dfe.index_axis.title = "Time (ns)" plot_h_dfe.y_axis.title = "Impulse Response (V/ns)" plot_h_dfe.legend.visible = True plot_h_dfe.legend.align = "ur" plot_h_dfe.index_range = plot_h_chnl.index_range # Zoom x-axes in tandem. container_h = GridPlotContainer(shape=(2, 2)) container_h.add(plot_h_chnl) container_h.add(plot_h_tx) container_h.add(plot_h_ctle) container_h.add(plot_h_dfe) self.plots_h = container_h # - Step Responses tab plot_s_chnl = Plot(plotdata, padding_left=75) plot_s_chnl.plot(("t_ns_chnl", "chnl_s"), type="line", color="blue", name="Incremental") plot_s_chnl.title = post_chnl_str plot_s_chnl.index_axis.title = "Time (ns)" plot_s_chnl.y_axis.title = "Step Response (V)" plot_s_chnl.legend.visible = True plot_s_chnl.legend.align = "lr" zoom_s = ZoomTool(plot_s_chnl, tool_mode="range", axis="index", always_on=False) plot_s_chnl.overlays.append(zoom_s) plot_s_tx = Plot(plotdata, padding_left=75) plot_s_tx.plot(("t_ns_chnl", "tx_s"), type="line", color="blue", name="Incremental") plot_s_tx.plot(("t_ns_chnl", "tx_out_s"), type="line", color="red", name="Cumulative") plot_s_tx.title = post_tx_str plot_s_tx.index_axis.title = "Time (ns)" plot_s_tx.y_axis.title = "Step Response (V)" plot_s_tx.legend.visible = True plot_s_tx.legend.align = "lr" plot_s_tx.index_range = plot_s_chnl.index_range # Zoom x-axes in tandem. plot_s_ctle = Plot(plotdata, padding_left=75) plot_s_ctle.plot(("t_ns_chnl", "ctle_s"), type="line", color="blue", name="Incremental") plot_s_ctle.plot(("t_ns_chnl", "ctle_out_s"), type="line", color="red", name="Cumulative") plot_s_ctle.title = post_ctle_str plot_s_ctle.index_axis.title = "Time (ns)" plot_s_ctle.y_axis.title = "Step Response (V)" plot_s_ctle.legend.visible = True plot_s_ctle.legend.align = "lr" plot_s_ctle.index_range = plot_s_chnl.index_range # Zoom x-axes in tandem. plot_s_dfe = Plot(plotdata, padding_left=75) plot_s_dfe.plot(("t_ns_chnl", "dfe_s"), type="line", color="blue", name="Incremental") plot_s_dfe.plot(("t_ns_chnl", "dfe_out_s"), type="line", color="red", name="Cumulative") plot_s_dfe.title = post_dfe_str plot_s_dfe.index_axis.title = "Time (ns)" plot_s_dfe.y_axis.title = "Step Response (V)" plot_s_dfe.legend.visible = True plot_s_dfe.legend.align = "lr" plot_s_dfe.index_range = plot_s_chnl.index_range # Zoom x-axes in tandem. container_s = GridPlotContainer(shape=(2, 2)) container_s.add(plot_s_chnl) container_s.add(plot_s_tx) container_s.add(plot_s_ctle) container_s.add(plot_s_dfe) self.plots_s = container_s # - Pulse Responses tab plot_p_chnl = Plot(plotdata, padding_left=75) plot_p_chnl.plot(("t_ns_chnl", "chnl_p"), type="line", color="blue", name="Incremental") plot_p_chnl.title = post_chnl_str plot_p_chnl.index_axis.title = "Time (ns)" plot_p_chnl.y_axis.title = "Pulse Response (V)" plot_p_chnl.legend.visible = True plot_p_chnl.legend.align = "ur" zoom_p = ZoomTool(plot_p_chnl, tool_mode="range", axis="index", always_on=False) plot_p_chnl.overlays.append(zoom_p) plot_p_tx = Plot(plotdata, padding_left=75) plot_p_tx.plot(("t_ns_chnl", "tx_out_p"), type="line", color="red", name="Cumulative") plot_p_tx.title = post_tx_str plot_p_tx.index_axis.title = "Time (ns)" plot_p_tx.y_axis.title = "Pulse Response (V)" plot_p_tx.legend.visible = True plot_p_tx.legend.align = "ur" plot_p_tx.index_range = plot_p_chnl.index_range # Zoom x-axes in tandem. plot_p_ctle = Plot(plotdata, padding_left=75) plot_p_ctle.plot(("t_ns_chnl", "ctle_out_p"), type="line", color="red", name="Cumulative") plot_p_ctle.title = post_ctle_str plot_p_ctle.index_axis.title = "Time (ns)" plot_p_ctle.y_axis.title = "Pulse Response (V)" plot_p_ctle.legend.visible = True plot_p_ctle.legend.align = "ur" plot_p_ctle.index_range = plot_p_chnl.index_range # Zoom x-axes in tandem. plot_p_dfe = Plot(plotdata, padding_left=75) plot_p_dfe.plot(("t_ns_chnl", "dfe_out_p"), type="line", color="red", name="Cumulative") plot_p_dfe.title = post_dfe_str plot_p_dfe.index_axis.title = "Time (ns)" plot_p_dfe.y_axis.title = "Pulse Response (V)" plot_p_dfe.legend.visible = True plot_p_dfe.legend.align = "ur" plot_p_dfe.index_range = plot_p_chnl.index_range # Zoom x-axes in tandem. container_p = GridPlotContainer(shape=(2, 2)) container_p.add(plot_p_chnl) container_p.add(plot_p_tx) container_p.add(plot_p_ctle) container_p.add(plot_p_dfe) self.plots_p = container_p # - Frequency Responses tab plot_H_chnl = Plot(plotdata, padding_left=75) plot_H_chnl.plot(("f_GHz", "chnl_H"), type="line", color="blue", name="Original Impulse", index_scale="log") plot_H_chnl.plot(("f_GHz", "chnl_trimmed_H"), type="line", color="red", name="Trimmed Impulse", index_scale="log") plot_H_chnl.title = post_chnl_str plot_H_chnl.index_axis.title = "Frequency (GHz)" plot_H_chnl.y_axis.title = "Frequency Response (dB)" plot_H_chnl.index_range.low_setting = 0.01 plot_H_chnl.index_range.high_setting = 40.0 plot_H_chnl.legend.visible = True plot_H_chnl.legend.align = "ll" plot_H_tx = Plot(plotdata, padding_left=75) plot_H_tx.plot(("f_GHz", "tx_H"), type="line", color="blue", name="Incremental", index_scale="log") plot_H_tx.plot(("f_GHz", "tx_out_H"), type="line", color="red", name="Cumulative", index_scale="log") plot_H_tx.title = post_tx_str plot_H_tx.index_axis.title = "Frequency (GHz)" plot_H_tx.y_axis.title = "Frequency Response (dB)" plot_H_tx.index_range.low_setting = 0.01 plot_H_tx.index_range.high_setting = 40.0 plot_H_tx.legend.visible = True plot_H_tx.legend.align = "ll" plot_H_ctle = Plot(plotdata, padding_left=75) plot_H_ctle.plot(("f_GHz", "ctle_H"), type="line", color="blue", name="Incremental", index_scale="log") plot_H_ctle.plot(("f_GHz", "ctle_out_H"), type="line", color="red", name="Cumulative", index_scale="log") plot_H_ctle.title = post_ctle_str plot_H_ctle.index_axis.title = "Frequency (GHz)" plot_H_ctle.y_axis.title = "Frequency Response (dB)" plot_H_ctle.index_range.low_setting = 0.01 plot_H_ctle.index_range.high_setting = 40.0 plot_H_ctle.value_range.low_setting = -40.0 plot_H_ctle.legend.visible = True plot_H_ctle.legend.align = "ll" plot_H_chnl.value_range = plot_H_ctle.value_range plot_H_tx.value_range = plot_H_ctle.value_range plot_H_dfe = Plot(plotdata, padding_left=75) plot_H_dfe.plot(("f_GHz", "dfe_H"), type="line", color="blue", name="Incremental", index_scale="log") plot_H_dfe.plot(("f_GHz", "dfe_out_H"), type="line", color="red", name="Cumulative", index_scale="log") plot_H_dfe.title = post_dfe_str plot_H_dfe.index_axis.title = "Frequency (GHz)" plot_H_dfe.y_axis.title = "Frequency Response (dB)" plot_H_dfe.index_range.low_setting = 0.01 plot_H_dfe.index_range.high_setting = 40.0 plot_H_dfe.value_range = plot_H_ctle.value_range plot_H_dfe.legend.visible = True plot_H_dfe.legend.align = "ll" container_H = GridPlotContainer(shape=(2, 2)) container_H.add(plot_H_chnl) container_H.add(plot_H_tx) container_H.add(plot_H_ctle) container_H.add(plot_H_dfe) self.plots_H = container_H # - Outputs tab plot_out_chnl = Plot(plotdata, padding_left=75) plot_out_chnl.plot(("t_ns", "ideal_signal"), type="line", color="lightgrey") plot_out_chnl.plot(("t_ns", "chnl_out"), type="line", color="blue") plot_out_chnl.title = post_chnl_str plot_out_chnl.index_axis.title = "Time (ns)" plot_out_chnl.y_axis.title = "Output (V)" plot_out_chnl.tools.append(PanTool(plot_out_chnl, constrain=True, constrain_key=None, constrain_direction="x")) zoom_out_chnl = ZoomTool(plot_out_chnl, tool_mode="range", axis="index", always_on=False) plot_out_chnl.overlays.append(zoom_out_chnl) plot_out_tx = Plot(plotdata, padding_left=75) plot_out_tx.plot(("t_ns", "tx_out"), type="line", color="blue") plot_out_tx.title = post_tx_str plot_out_tx.index_axis.title = "Time (ns)" plot_out_tx.y_axis.title = "Output (V)" plot_out_tx.index_range = plot_out_chnl.index_range # Zoom x-axes in tandem. plot_out_ctle = Plot(plotdata, padding_left=75) plot_out_ctle.plot(("t_ns", "ctle_out"), type="line", color="blue") plot_out_ctle.title = post_ctle_str plot_out_ctle.index_axis.title = "Time (ns)" plot_out_ctle.y_axis.title = "Output (V)" plot_out_ctle.index_range = plot_out_chnl.index_range # Zoom x-axes in tandem. plot_out_dfe = Plot(plotdata, padding_left=75) plot_out_dfe.plot(("t_ns", "dfe_out"), type="line", color="blue") plot_out_dfe.title = post_dfe_str plot_out_dfe.index_axis.title = "Time (ns)" plot_out_dfe.y_axis.title = "Output (V)" plot_out_dfe.index_range = plot_out_chnl.index_range # Zoom x-axes in tandem. container_out = GridPlotContainer(shape=(2, 2)) container_out.add(plot_out_chnl) container_out.add(plot_out_tx) container_out.add(plot_out_ctle) container_out.add(plot_out_dfe) self.plots_out = container_out # - Eye Diagrams tab seg_map = dict( red=[ (0.00, 0.00, 0.00), # black (0.00001, 0.00, 0.00), # blue (0.15, 0.00, 0.00), # cyan (0.30, 0.00, 0.00), # green (0.45, 1.00, 1.00), # yellow (0.60, 1.00, 1.00), # orange (0.75, 1.00, 1.00), # red (0.90, 1.00, 1.00), # pink (1.00, 1.00, 1.00), # white ], green=[ (0.00, 0.00, 0.00), # black (0.00001, 0.00, 0.00), # blue (0.15, 0.50, 0.50), # cyan (0.30, 0.50, 0.50), # green (0.45, 1.00, 1.00), # yellow (0.60, 0.50, 0.50), # orange (0.75, 0.00, 0.00), # red (0.90, 0.50, 0.50), # pink (1.00, 1.00, 1.00), # white ], blue=[ (0.00, 0.00, 0.00), # black (1e-18, 0.50, 0.50), # blue (0.15, 0.50, 0.50), # cyan (0.30, 0.00, 0.00), # green (0.45, 0.00, 0.00), # yellow (0.60, 0.00, 0.00), # orange (0.75, 0.00, 0.00), # red (0.90, 0.50, 0.50), # pink (1.00, 1.00, 1.00), # white ], ) clr_map = ColorMapper.from_segment_map(seg_map) self.clr_map = clr_map plot_eye_chnl = Plot(plotdata, padding_left=75) plot_eye_chnl.img_plot("eye_chnl", colormap=clr_map) plot_eye_chnl.y_direction = "normal" plot_eye_chnl.components[0].y_direction = "normal" plot_eye_chnl.title = post_chnl_str plot_eye_chnl.x_axis.title = "Time (ps)" plot_eye_chnl.x_axis.orientation = "bottom" plot_eye_chnl.y_axis.title = "Signal Level (V)" plot_eye_chnl.x_grid.visible = True plot_eye_chnl.y_grid.visible = True plot_eye_chnl.x_grid.line_color = "gray" plot_eye_chnl.y_grid.line_color = "gray" plot_eye_tx = Plot(plotdata, padding_left=75) plot_eye_tx.img_plot("eye_tx", colormap=clr_map) plot_eye_tx.y_direction = "normal" plot_eye_tx.components[0].y_direction = "normal" plot_eye_tx.title = post_tx_str plot_eye_tx.x_axis.title = "Time (ps)" plot_eye_tx.x_axis.orientation = "bottom" plot_eye_tx.y_axis.title = "Signal Level (V)" plot_eye_tx.x_grid.visible = True plot_eye_tx.y_grid.visible = True plot_eye_tx.x_grid.line_color = "gray" plot_eye_tx.y_grid.line_color = "gray" plot_eye_ctle = Plot(plotdata, padding_left=75) plot_eye_ctle.img_plot("eye_ctle", colormap=clr_map) plot_eye_ctle.y_direction = "normal" plot_eye_ctle.components[0].y_direction = "normal" plot_eye_ctle.title = post_ctle_str plot_eye_ctle.x_axis.title = "Time (ps)" plot_eye_ctle.x_axis.orientation = "bottom" plot_eye_ctle.y_axis.title = "Signal Level (V)" plot_eye_ctle.x_grid.visible = True plot_eye_ctle.y_grid.visible = True plot_eye_ctle.x_grid.line_color = "gray" plot_eye_ctle.y_grid.line_color = "gray" plot_eye_dfe = Plot(plotdata, padding_left=75) plot_eye_dfe.img_plot("eye_dfe", colormap=clr_map) plot_eye_dfe.y_direction = "normal" plot_eye_dfe.components[0].y_direction = "normal" plot_eye_dfe.title = post_dfe_str plot_eye_dfe.x_axis.title = "Time (ps)" plot_eye_dfe.x_axis.orientation = "bottom" plot_eye_dfe.y_axis.title = "Signal Level (V)" plot_eye_dfe.x_grid.visible = True plot_eye_dfe.y_grid.visible = True plot_eye_dfe.x_grid.line_color = "gray" plot_eye_dfe.y_grid.line_color = "gray" container_eye = GridPlotContainer(shape=(2, 2)) container_eye.add(plot_eye_chnl) container_eye.add(plot_eye_tx) container_eye.add(plot_eye_ctle) container_eye.add(plot_eye_dfe) self.plots_eye = container_eye # - Jitter Distributions tab plot_jitter_dist_chnl = Plot(plotdata, padding_left=75) plot_jitter_dist_chnl.plot(("jitter_bins", "jitter_chnl"), type="line", color="blue", name="Measured") plot_jitter_dist_chnl.plot(("jitter_bins", "jitter_ext_chnl"), type="line", color="red", name="Extrapolated") plot_jitter_dist_chnl.title = post_chnl_str plot_jitter_dist_chnl.index_axis.title = "Time (ps)" plot_jitter_dist_chnl.value_axis.title = "Count" plot_jitter_dist_chnl.legend.visible = True plot_jitter_dist_chnl.legend.align = "ur" plot_jitter_dist_tx = Plot(plotdata, padding_left=75) plot_jitter_dist_tx.plot(("jitter_bins", "jitter_tx"), type="line", color="blue", name="Measured") plot_jitter_dist_tx.plot(("jitter_bins", "jitter_ext_tx"), type="line", color="red", name="Extrapolated") plot_jitter_dist_tx.title = post_tx_str plot_jitter_dist_tx.index_axis.title = "Time (ps)" plot_jitter_dist_tx.value_axis.title = "Count" plot_jitter_dist_tx.legend.visible = True plot_jitter_dist_tx.legend.align = "ur" plot_jitter_dist_ctle = Plot(plotdata, padding_left=75) plot_jitter_dist_ctle.plot(("jitter_bins", "jitter_ctle"), type="line", color="blue", name="Measured") plot_jitter_dist_ctle.plot(("jitter_bins", "jitter_ext_ctle"), type="line", color="red", name="Extrapolated") plot_jitter_dist_ctle.title = post_ctle_str plot_jitter_dist_ctle.index_axis.title = "Time (ps)" plot_jitter_dist_ctle.value_axis.title = "Count" plot_jitter_dist_ctle.legend.visible = True plot_jitter_dist_ctle.legend.align = "ur" plot_jitter_dist_dfe = Plot(plotdata, padding_left=75) plot_jitter_dist_dfe.plot(("jitter_bins", "jitter_dfe"), type="line", color="blue", name="Measured") plot_jitter_dist_dfe.plot(("jitter_bins", "jitter_ext_dfe"), type="line", color="red", name="Extrapolated") plot_jitter_dist_dfe.title = post_dfe_str plot_jitter_dist_dfe.index_axis.title = "Time (ps)" plot_jitter_dist_dfe.value_axis.title = "Count" plot_jitter_dist_dfe.legend.visible = True plot_jitter_dist_dfe.legend.align = "ur" container_jitter_dist = GridPlotContainer(shape=(2, 2)) container_jitter_dist.add(plot_jitter_dist_chnl) container_jitter_dist.add(plot_jitter_dist_tx) container_jitter_dist.add(plot_jitter_dist_ctle) container_jitter_dist.add(plot_jitter_dist_dfe) self.plots_jitter_dist = container_jitter_dist # - Jitter Spectrums tab plot_jitter_spec_chnl = Plot(plotdata) plot_jitter_spec_chnl.plot(("f_MHz", "jitter_spectrum_chnl"), type="line", color="blue", name="Total") plot_jitter_spec_chnl.plot( ("f_MHz", "jitter_ind_spectrum_chnl"), type="line", color="red", name="Data Independent" ) plot_jitter_spec_chnl.plot(("f_MHz", "thresh_chnl"), type="line", color="magenta", name="Pj Threshold") plot_jitter_spec_chnl.title = post_chnl_str plot_jitter_spec_chnl.index_axis.title = "Frequency (MHz)" plot_jitter_spec_chnl.value_axis.title = "|FFT(TIE)| (dBui)" plot_jitter_spec_chnl.tools.append( PanTool(plot_jitter_spec_chnl, constrain=True, constrain_key=None, constrain_direction="x") ) zoom_jitter_spec_chnl = ZoomTool(plot_jitter_spec_chnl, tool_mode="range", axis="index", always_on=False) plot_jitter_spec_chnl.overlays.append(zoom_jitter_spec_chnl) plot_jitter_spec_chnl.legend.visible = True plot_jitter_spec_chnl.legend.align = "lr" plot_jitter_spec_tx = Plot(plotdata) plot_jitter_spec_tx.plot(("f_MHz", "jitter_spectrum_tx"), type="line", color="blue", name="Total") plot_jitter_spec_tx.plot(("f_MHz", "jitter_ind_spectrum_tx"), type="line", color="red", name="Data Independent") plot_jitter_spec_tx.plot(("f_MHz", "thresh_tx"), type="line", color="magenta", name="Pj Threshold") plot_jitter_spec_tx.title = post_tx_str plot_jitter_spec_tx.index_axis.title = "Frequency (MHz)" plot_jitter_spec_tx.value_axis.title = "|FFT(TIE)| (dBui)" plot_jitter_spec_tx.value_range.low_setting = -40.0 plot_jitter_spec_tx.index_range = plot_jitter_spec_chnl.index_range # Zoom x-axes in tandem. plot_jitter_spec_tx.legend.visible = True plot_jitter_spec_tx.legend.align = "lr" plot_jitter_spec_chnl.value_range = plot_jitter_spec_tx.value_range plot_jitter_spec_ctle = Plot(plotdata) plot_jitter_spec_ctle.plot(("f_MHz", "jitter_spectrum_ctle"), type="line", color="blue", name="Total") plot_jitter_spec_ctle.plot( ("f_MHz", "jitter_ind_spectrum_ctle"), type="line", color="red", name="Data Independent" ) plot_jitter_spec_ctle.plot(("f_MHz", "thresh_ctle"), type="line", color="magenta", name="Pj Threshold") plot_jitter_spec_ctle.title = post_ctle_str plot_jitter_spec_ctle.index_axis.title = "Frequency (MHz)" plot_jitter_spec_ctle.value_axis.title = "|FFT(TIE)| (dBui)" plot_jitter_spec_ctle.index_range = plot_jitter_spec_chnl.index_range # Zoom x-axes in tandem. plot_jitter_spec_ctle.legend.visible = True plot_jitter_spec_ctle.legend.align = "lr" plot_jitter_spec_ctle.value_range = plot_jitter_spec_tx.value_range plot_jitter_spec_dfe = Plot(plotdata) plot_jitter_spec_dfe.plot(("f_MHz_dfe", "jitter_spectrum_dfe"), type="line", color="blue", name="Total") plot_jitter_spec_dfe.plot( ("f_MHz_dfe", "jitter_ind_spectrum_dfe"), type="line", color="red", name="Data Independent" ) plot_jitter_spec_dfe.plot(("f_MHz_dfe", "thresh_dfe"), type="line", color="magenta", name="Pj Threshold") plot_jitter_spec_dfe.title = post_dfe_str plot_jitter_spec_dfe.index_axis.title = "Frequency (MHz)" plot_jitter_spec_dfe.value_axis.title = "|FFT(TIE)| (dBui)" plot_jitter_spec_dfe.index_range = plot_jitter_spec_chnl.index_range # Zoom x-axes in tandem. plot_jitter_spec_dfe.legend.visible = True plot_jitter_spec_dfe.legend.align = "lr" plot_jitter_spec_dfe.value_range = plot_jitter_spec_tx.value_range container_jitter_spec = GridPlotContainer(shape=(2, 2)) container_jitter_spec.add(plot_jitter_spec_chnl) container_jitter_spec.add(plot_jitter_spec_tx) container_jitter_spec.add(plot_jitter_spec_ctle) container_jitter_spec.add(plot_jitter_spec_dfe) self.plots_jitter_spec = container_jitter_spec # - Bathtub Curves tab plot_bathtub_chnl = Plot(plotdata) plot_bathtub_chnl.plot(("jitter_bins", "bathtub_chnl"), type="line", color="blue") plot_bathtub_chnl.value_range.high_setting = 0 plot_bathtub_chnl.value_range.low_setting = -18 plot_bathtub_chnl.value_axis.tick_interval = 3 plot_bathtub_chnl.title = post_chnl_str plot_bathtub_chnl.index_axis.title = "Time (ps)" plot_bathtub_chnl.value_axis.title = "Log10(P(Transition occurs inside.))" plot_bathtub_tx = Plot(plotdata) plot_bathtub_tx.plot(("jitter_bins", "bathtub_tx"), type="line", color="blue") plot_bathtub_tx.value_range.high_setting = 0 plot_bathtub_tx.value_range.low_setting = -18 plot_bathtub_tx.value_axis.tick_interval = 3 plot_bathtub_tx.title = post_tx_str plot_bathtub_tx.index_axis.title = "Time (ps)" plot_bathtub_tx.value_axis.title = "Log10(P(Transition occurs inside.))" plot_bathtub_ctle = Plot(plotdata) plot_bathtub_ctle.plot(("jitter_bins", "bathtub_ctle"), type="line", color="blue") plot_bathtub_ctle.value_range.high_setting = 0 plot_bathtub_ctle.value_range.low_setting = -18 plot_bathtub_ctle.value_axis.tick_interval = 3 plot_bathtub_ctle.title = post_ctle_str plot_bathtub_ctle.index_axis.title = "Time (ps)" plot_bathtub_ctle.value_axis.title = "Log10(P(Transition occurs inside.))" plot_bathtub_dfe = Plot(plotdata) plot_bathtub_dfe.plot(("jitter_bins", "bathtub_dfe"), type="line", color="blue") plot_bathtub_dfe.value_range.high_setting = 0 plot_bathtub_dfe.value_range.low_setting = -18 plot_bathtub_dfe.value_axis.tick_interval = 3 plot_bathtub_dfe.title = post_dfe_str plot_bathtub_dfe.index_axis.title = "Time (ps)" plot_bathtub_dfe.value_axis.title = "Log10(P(Transition occurs inside.))" container_bathtub = GridPlotContainer(shape=(2, 2)) container_bathtub.add(plot_bathtub_chnl) container_bathtub.add(plot_bathtub_tx) container_bathtub.add(plot_bathtub_ctle) container_bathtub.add(plot_bathtub_dfe) self.plots_bathtub = container_bathtub update_eyes(self)
def update_results(self): """ Updates all plot data used by GUI. Args: self(PyBERT): Reference to an instance of the *PyBERT* class. """ # Copy globals into local namespace. ui = self.ui samps_per_ui = self.nspui eye_uis = self.eye_uis num_ui = self.nui clock_times = self.clock_times f = self.f t = self.t t_ns = self.t_ns t_ns_chnl = self.t_ns_chnl conv_dly_ix = self.conv_dly_ix n_taps = self.n_taps Ts = t[1] ignore_until = (num_ui - eye_uis) * ui ignore_samps = (num_ui - eye_uis) * samps_per_ui # Misc. f_GHz = f[:len(f) // 2] / 1.e9 len_f_GHz = len(f_GHz) self.plotdata.set_data("f_GHz", f_GHz[1:]) self.plotdata.set_data("t_ns", t_ns) self.plotdata.set_data("t_ns_chnl", t_ns_chnl) # DFE. tap_weights = transpose(array(self.adaptation)) i = 1 for tap_weight in tap_weights: self.plotdata.set_data("tap%d_weights" % i, tap_weight) i += 1 self.plotdata.set_data("tap_weight_index", range(len(tap_weight))) if(self._old_n_taps != n_taps): new_plot = Plot(self.plotdata, auto_colors=['red', 'orange', 'yellow', 'green', 'blue', 'purple'], padding_left=75) for i in range(self.n_taps): new_plot.plot(("tap_weight_index", "tap%d_weights" % (i + 1)), type="line", color="auto", name="tap%d"%(i+1)) new_plot.title = "DFE Adaptation" new_plot.tools.append(PanTool(new_plot, constrain=True, constrain_key=None, constrain_direction='x')) zoom9 = ZoomTool(new_plot, tool_mode="range", axis='index', always_on=False) new_plot.overlays.append(zoom9) new_plot.legend.visible = True new_plot.legend.align = 'ul' self.plots_dfe.remove(self._dfe_plot) self.plots_dfe.insert(1, new_plot) self._dfe_plot = new_plot self._old_n_taps = n_taps clock_pers = diff(clock_times) start_t = t[where(self.lockeds)[0][0]] start_ix = where(clock_times > start_t)[0][0] (bin_counts, bin_edges) = histogram(clock_pers[start_ix:], bins=100) bin_centers = (bin_edges[:-1] + bin_edges[1:]) / 2. clock_spec = fft(clock_pers[start_ix:]) clock_spec = abs(clock_spec[:len(clock_spec) / 2]) spec_freqs = arange(len(clock_spec)) / (2. * len(clock_spec)) # In this case, fNyquist = half the bit rate. clock_spec /= clock_spec[1:].mean() # Normalize the mean non-d.c. value to 0 dB. self.plotdata.set_data("clk_per_hist_bins", bin_centers * 1.e12) # (ps) self.plotdata.set_data("clk_per_hist_vals", bin_counts) self.plotdata.set_data("clk_spec", 10. * log10(clock_spec[1:])) # Omit the d.c. value. self.plotdata.set_data("clk_freqs", spec_freqs[1:]) self.plotdata.set_data("dfe_out", self.dfe_out) self.plotdata.set_data("ui_ests", self.ui_ests) self.plotdata.set_data("clocks", self.clocks) self.plotdata.set_data("lockeds", self.lockeds) # Impulse responses self.plotdata.set_data("chnl_h", self.chnl_h * 1.e-9 / Ts) # Re-normalize to (V/ns), for plotting. self.plotdata.set_data("tx_h", self.tx_h * 1.e-9 / Ts) self.plotdata.set_data("tx_out_h", self.tx_out_h * 1.e-9 / Ts) self.plotdata.set_data("ctle_h", self.ctle_h * 1.e-9 / Ts) self.plotdata.set_data("ctle_out_h", self.ctle_out_h * 1.e-9 / Ts) self.plotdata.set_data("dfe_h", self.dfe_h * 1.e-9 / Ts) self.plotdata.set_data("dfe_out_h", self.dfe_out_h * 1.e-9 / Ts) # Step responses self.plotdata.set_data("chnl_s", self.chnl_s) self.plotdata.set_data("tx_s", self.tx_s) self.plotdata.set_data("tx_out_s", self.tx_out_s) self.plotdata.set_data("ctle_s", self.ctle_s) self.plotdata.set_data("ctle_out_s", self.ctle_out_s) self.plotdata.set_data("dfe_s", self.dfe_s) self.plotdata.set_data("dfe_out_s", self.dfe_out_s) # Pulse responses self.plotdata.set_data("chnl_p", self.chnl_p) self.plotdata.set_data("tx_out_p", self.tx_out_p) self.plotdata.set_data("ctle_out_p", self.ctle_out_p) self.plotdata.set_data("dfe_out_p", self.dfe_out_p) # Outputs self.plotdata.set_data("ideal_signal", self.ideal_signal) self.plotdata.set_data("chnl_out", self.chnl_out) self.plotdata.set_data("tx_out", self.rx_in) self.plotdata.set_data("ctle_out", self.ctle_out) self.plotdata.set_data("dfe_out", self.dfe_out) self.plotdata.set_data("auto_corr", self.auto_corr) # Frequency responses self.plotdata.set_data("chnl_H", 20. * log10(abs(self.chnl_H [1 : len_f_GHz]))) self.plotdata.set_data("chnl_trimmed_H", 20. * log10(abs(self.chnl_trimmed_H [1 : len_f_GHz]))) self.plotdata.set_data("tx_H", 20. * log10(abs(self.tx_H [1 : len_f_GHz]))) self.plotdata.set_data("tx_out_H", 20. * log10(abs(self.tx_out_H [1 : len_f_GHz]))) self.plotdata.set_data("ctle_H", 20. * log10(abs(self.ctle_H [1 : len_f_GHz]))) self.plotdata.set_data("ctle_out_H", 20. * log10(abs(self.ctle_out_H[1 : len_f_GHz]))) self.plotdata.set_data("dfe_H", 20. * log10(abs(self.dfe_H [1 : len_f_GHz]))) self.plotdata.set_data("dfe_out_H", 20. * log10(abs(self.dfe_out_H [1 : len_f_GHz]))) # Jitter distributions jitter_ext_chnl = self.jitter_ext_chnl # These are used, again, in bathtub curve generation, below. jitter_ext_tx = self.jitter_ext_tx jitter_ext_ctle = self.jitter_ext_ctle jitter_ext_dfe = self.jitter_ext_dfe self.plotdata.set_data("jitter_bins", array(self.jitter_bins) * 1.e12) self.plotdata.set_data("jitter_chnl", self.jitter_chnl) self.plotdata.set_data("jitter_ext_chnl", jitter_ext_chnl) self.plotdata.set_data("jitter_tx", self.jitter_tx) self.plotdata.set_data("jitter_ext_tx", jitter_ext_tx) self.plotdata.set_data("jitter_ctle", self.jitter_ctle) self.plotdata.set_data("jitter_ext_ctle", jitter_ext_ctle) self.plotdata.set_data("jitter_dfe", self.jitter_dfe) self.plotdata.set_data("jitter_ext_dfe", jitter_ext_dfe) # Jitter spectrums log10_ui = log10(ui) self.plotdata.set_data("f_MHz", self.f_MHz[1:]) self.plotdata.set_data("f_MHz_dfe", self.f_MHz_dfe[1:]) self.plotdata.set_data("jitter_spectrum_chnl", 10. * (log10(self.jitter_spectrum_chnl [1:]) - log10_ui)) self.plotdata.set_data("jitter_ind_spectrum_chnl", 10. * (log10(self.jitter_ind_spectrum_chnl [1:]) - log10_ui)) self.plotdata.set_data("thresh_chnl", 10. * (log10(self.thresh_chnl [1:]) - log10_ui)) self.plotdata.set_data("jitter_spectrum_tx", 10. * (log10(self.jitter_spectrum_tx [1:]) - log10_ui)) self.plotdata.set_data("jitter_ind_spectrum_tx", 10. * (log10(self.jitter_ind_spectrum_tx [1:]) - log10_ui)) self.plotdata.set_data("thresh_tx", 10. * (log10(self.thresh_tx [1:]) - log10_ui)) self.plotdata.set_data("jitter_spectrum_ctle", 10. * (log10(self.jitter_spectrum_ctle [1:]) - log10_ui)) self.plotdata.set_data("jitter_ind_spectrum_ctle", 10. * (log10(self.jitter_ind_spectrum_ctle [1:]) - log10_ui)) self.plotdata.set_data("thresh_ctle", 10. * (log10(self.thresh_ctle [1:]) - log10_ui)) self.plotdata.set_data("jitter_spectrum_dfe", 10. * (log10(self.jitter_spectrum_dfe [1:]) - log10_ui)) self.plotdata.set_data("jitter_ind_spectrum_dfe", 10. * (log10(self.jitter_ind_spectrum_dfe [1:]) - log10_ui)) self.plotdata.set_data("thresh_dfe", 10. * (log10(self.thresh_dfe [1:]) - log10_ui)) self.plotdata.set_data("jitter_rejection_ratio", self.jitter_rejection_ratio[1:]) # Bathtubs half_len = len(jitter_ext_chnl) / 2 # - Channel bathtub_chnl = list(cumsum(jitter_ext_chnl[-1 : -(half_len + 1) : -1])) bathtub_chnl.reverse() bathtub_chnl = array(bathtub_chnl + list(cumsum(jitter_ext_chnl[:half_len + 1]))) bathtub_chnl = where(bathtub_chnl < MIN_BATHTUB_VAL, 0.1 * MIN_BATHTUB_VAL * ones(len(bathtub_chnl)), bathtub_chnl) # To avoid Chaco log scale plot wierdness. self.plotdata.set_data("bathtub_chnl", log10(bathtub_chnl)) # - Tx bathtub_tx = list(cumsum(jitter_ext_tx[-1 : -(half_len + 1) : -1])) bathtub_tx.reverse() bathtub_tx = array(bathtub_tx + list(cumsum(jitter_ext_tx[:half_len + 1]))) bathtub_tx = where(bathtub_tx < MIN_BATHTUB_VAL, 0.1 * MIN_BATHTUB_VAL * ones(len(bathtub_tx)), bathtub_tx) # To avoid Chaco log scale plot wierdness. self.plotdata.set_data("bathtub_tx", log10(bathtub_tx)) # - CTLE bathtub_ctle = list(cumsum(jitter_ext_ctle[-1 : -(half_len + 1) : -1])) bathtub_ctle.reverse() bathtub_ctle = array(bathtub_ctle + list(cumsum(jitter_ext_ctle[:half_len + 1]))) bathtub_ctle = where(bathtub_ctle < MIN_BATHTUB_VAL, 0.1 * MIN_BATHTUB_VAL * ones(len(bathtub_ctle)), bathtub_ctle) # To avoid Chaco log scale plot wierdness. self.plotdata.set_data("bathtub_ctle", log10(bathtub_ctle)) # - DFE bathtub_dfe = list(cumsum(jitter_ext_dfe[-1 : -(half_len + 1) : -1])) bathtub_dfe.reverse() bathtub_dfe = array(bathtub_dfe + list(cumsum(jitter_ext_dfe[:half_len + 1]))) bathtub_dfe = where(bathtub_dfe < MIN_BATHTUB_VAL, 0.1 * MIN_BATHTUB_VAL * ones(len(bathtub_dfe)), bathtub_dfe) # To avoid Chaco log scale plot wierdness. self.plotdata.set_data("bathtub_dfe", log10(bathtub_dfe)) # Eyes width = 2 * samps_per_ui xs = linspace(-ui * 1.e12, ui * 1.e12, width) height = 100 y_max = 1.1 * max(abs(array(self.chnl_out))) eye_chnl = calc_eye(ui, samps_per_ui, height, self.chnl_out[ignore_samps:], y_max) y_max = 1.1 * max(abs(array(self.rx_in))) eye_tx = calc_eye(ui, samps_per_ui, height, self.rx_in[ignore_samps:], y_max) y_max = 1.1 * max(abs(array(self.ctle_out))) eye_ctle = calc_eye(ui, samps_per_ui, height, self.ctle_out[ignore_samps:], y_max) i = 0 while(clock_times[i] <= ignore_until): i += 1 assert i < len(clock_times), "ERROR: Insufficient coverage in 'clock_times' vector." y_max = 1.1 * max(abs(array(self.dfe_out))) eye_dfe = calc_eye(ui, samps_per_ui, height, self.dfe_out, y_max, clock_times[i:]) self.plotdata.set_data("eye_index", xs) self.plotdata.set_data("eye_chnl", eye_chnl) self.plotdata.set_data("eye_tx", eye_tx) self.plotdata.set_data("eye_ctle", eye_ctle) self.plotdata.set_data("eye_dfe", eye_dfe)
class myImagePlot(HasTraits): # container for all plots container = Instance(HPlotContainer) # Plot components within this container: color_plot = Instance(CMapImagePlot) vertical_cross_plot = Instance(Plot) horizontal_cross_plot = Instance(Plot) colorbar = Instance(ColorBar) # plot data pd_all = Instance(ArrayPlotData) pd_horiz=Instance(ArrayPlotData) pd_vert=Instance(ArrayPlotData) #private data storage _imag_index=Instance(GridDataSource) _image_value=Instance(ImageData) traits_view = View( Item('container', editor=ComponentEditor(), show_label=False), width=1000, height=700, resizable=True, title="Chaco Plot") def __init__(self, x,y,z): super(myImagePlot, self).__init__() self.pd_all = ArrayPlotData(imagedata = z) self.pd_horiz = ArrayPlotData(x=x, horiz=z[4, :]) self.pd_vert = ArrayPlotData(y=y, vert=z[:,5]) self._imag_index = GridDataSource(xdata=x, ydata=y, sort_order=("ascending","ascending")) index_mapper = GridMapper(range=DataRange2D(self._imag_index)) self._imag_index.on_trait_change(self._metadata_changed, "metadata_changed") self._image_value = ImageData(data=z, value_depth=1) color_mapper = jet(DataRange1D(self._image_value)) self.color_plot= CMapImagePlot( index=self._imag_index, index_mapper=index_mapper, value=self._image_value, value_mapper=color_mapper, padding=20, use_backbuffer=True, unified_draw=True) #Add axes to image plot left = PlotAxis(orientation='left', title= "Frequency (GHz)", mapper=self.color_plot.index_mapper._ymapper, component=self.color_plot) self.color_plot.overlays.append(left) bottom = PlotAxis(orientation='bottom', title= "Time (us)", mapper=self.color_plot.index_mapper._xmapper, component=self.color_plot) self.color_plot.overlays.append(bottom) self.color_plot.tools.append(PanTool(self.color_plot, constrain_key="shift")) self.color_plot.overlays.append(ZoomTool(component=self.color_plot, tool_mode="box", always_on=False)) #Add line inspector tool for horizontal and vertical self.color_plot.overlays.append(LineInspector(component=self.color_plot, axis='index_x', inspect_mode="indexed", write_metadata=True, is_listener=True, color="white")) self.color_plot.overlays.append(LineInspector(component=self.color_plot, axis='index_y', inspect_mode="indexed", write_metadata=True, color="white", is_listener=True)) myrange = DataRange1D(low=amin(z), high=amax(z)) cmap=jet self.colormap = cmap(myrange) # Create a colorbar cbar_index_mapper = LinearMapper(range=myrange) self.colorbar = ColorBar(index_mapper=cbar_index_mapper, plot=self.color_plot, padding_top=self.color_plot.padding_top, padding_bottom=self.color_plot.padding_bottom, padding_right=40, resizable='v', width=30)#, ytitle="Magvec (mV)") #create horizontal line plot self.horiz_cross_plot = Plot(self.pd_horiz, resizable="h") self.horiz_cross_plot.height = 100 self.horiz_cross_plot.padding = 20 self.horiz_cross_plot.plot(("x", "horiz"))#, #line_style="dot") # self.cross_plot.plot(("scatter_index","scatter_value","scatter_color"), # type="cmap_scatter", # name="dot", # color_mapper=self._cmap(image_value_range), # marker="circle", # marker_size=8) self.horiz_cross_plot.index_range = self.color_plot.index_range.x_range #create vertical line plot self.vert_cross_plot = Plot(self.pd_vert, width = 140, orientation="v", resizable="v", padding=20, padding_bottom=160) self.vert_cross_plot.plot(("y", "vert"))#, # line_style="dot") # self.vert_cross_plot.xtitle="Magvec (mV)" # self.vertica_cross_plot.plot(("vertical_scatter_index", # "vertical_scatter_value", # "vertical_scatter_color"), # type="cmap_scatter", # name="dot", # color_mapper=self._cmap(image_value_range), # marker="circle", # marker_size=8) self.vert_cross_plot.index_range = self.color_plot.index_range.y_range # Create a container and add components self.container = HPlotContainer(padding=40, fill_padding=True, bgcolor = "white", use_backbuffer=False) inner_cont = VPlotContainer(padding=0, use_backbuffer=True) inner_cont.add(self.horiz_cross_plot) inner_cont.add(self.color_plot) self.container.add(self.colorbar) self.container.add(inner_cont) self.container.add(self.vert_cross_plot) def _metadata_changed(self, old, new): """ This function takes out a cross section from the image data, based on the line inspector selections, and updates the line and scatter plots.""" #self.cross_plot.value_range.low = self.minz #self.cross_plot.value_range.high = self.maxz #self.cross_plot2.value_range.low = self.minz #self.cross_plot2.value_range.high = self.maxz if self._imag_index.metadata.has_key("selections"): x_ndx, y_ndx = self._imag_index.metadata["selections"] if y_ndx and x_ndx: # xdata, ydata = self._image_index.get_data() # xdata, ydata = xdata.get_data(), ydata.get_data() self.pd_horiz.set_data("horiz", self._image_value.data[y_ndx,:]) self.pd_vert.set_data("vert", self._image_value.data[:,x_ndx])
def __init__(self, link): super(SolutionView, self).__init__() self.log_file = None self.vel_log_file = None self.plot_data = ArrayPlotData(lat=[], lng=[], alt=[], t=[], cur_lat=[], cur_lng=[], cur_lat_ps=[], cur_lng_ps=[], lat_ps=[], lng_ps=[], alt_ps=[], t_ps=[]) self.plot = Plot(self.plot_data) # 1000 point buffer self.plot.plot(('lng', 'lat'), type='line', name='', color=(0, 0, 0.9, 0.1)) self.plot.plot(('lng', 'lat'), type='scatter', name='', color='blue', marker='dot', line_width=0.0, marker_size=1.0) self.plot.plot(('lng_ps', 'lat_ps'), type='line', name='', color=(1, 0.4, 0, 0.1)) self.plot.plot(('lng_ps', 'lat_ps'), type='scatter', name='', color='orange', marker='diamond', line_width=0.0, marker_size=1.0) # current values spp = self.plot.plot(('cur_lng', 'cur_lat'), type='scatter', name='SPP', color='blue', marker='plus', line_width=1.5, marker_size=5.0) rtk = self.plot.plot(('cur_lng_ps', 'cur_lat_ps'), type='scatter', name='RTK', color='orange', marker='plus', line_width=1.5, marker_size=5.0) plot_labels = ['SPP', 'RTK'] plots_legend = dict(zip(plot_labels, [spp, rtk])) self.plot.legend.plots = plots_legend self.plot.legend.visible = True self.plot.index_axis.tick_label_position = 'inside' self.plot.index_axis.tick_label_color = 'gray' self.plot.index_axis.tick_color = 'gray' self.plot.index_axis.title = 'Longitude (degrees)' self.plot.index_axis.title_spacing = 5 self.plot.value_axis.tick_label_position = 'inside' self.plot.value_axis.tick_label_color = 'gray' self.plot.value_axis.tick_color = 'gray' self.plot.value_axis.title = 'Latitude (degrees)' self.plot.value_axis.title_spacing = 5 self.plot.padding = (25, 25, 25, 25) self.plot.tools.append(PanTool(self.plot)) zt = ZoomTool(self.plot, zoom_factor=1.1, tool_mode="box", always_on=False) self.plot.overlays.append(zt) self.link = link self.link.add_callback(self._pos_llh_callback, SBP_MSG_POS_LLH) self.link.add_callback(self.vel_ned_callback, SBP_MSG_VEL_NED) self.link.add_callback(self.dops_callback, SBP_MSG_DOPS) self.link.add_callback(self.gps_time_callback, SBP_MSG_GPS_TIME) self.week = None self.nsec = 0 self.python_console_cmds = { 'solution': self, }
def __init__(self, x,y,z): super(myImagePlot, self).__init__() self.pd_all = ArrayPlotData(imagedata = z) self.pd_horiz = ArrayPlotData(x=x, horiz=z[4, :]) self.pd_vert = ArrayPlotData(y=y, vert=z[:,5]) self._imag_index = GridDataSource(xdata=x, ydata=y, sort_order=("ascending","ascending")) index_mapper = GridMapper(range=DataRange2D(self._imag_index)) self._imag_index.on_trait_change(self._metadata_changed, "metadata_changed") self._image_value = ImageData(data=z, value_depth=1) color_mapper = jet(DataRange1D(self._image_value)) self.color_plot= CMapImagePlot( index=self._imag_index, index_mapper=index_mapper, value=self._image_value, value_mapper=color_mapper, padding=20, use_backbuffer=True, unified_draw=True) #Add axes to image plot left = PlotAxis(orientation='left', title= "Frequency (GHz)", mapper=self.color_plot.index_mapper._ymapper, component=self.color_plot) self.color_plot.overlays.append(left) bottom = PlotAxis(orientation='bottom', title= "Time (us)", mapper=self.color_plot.index_mapper._xmapper, component=self.color_plot) self.color_plot.overlays.append(bottom) self.color_plot.tools.append(PanTool(self.color_plot, constrain_key="shift")) self.color_plot.overlays.append(ZoomTool(component=self.color_plot, tool_mode="box", always_on=False)) #Add line inspector tool for horizontal and vertical self.color_plot.overlays.append(LineInspector(component=self.color_plot, axis='index_x', inspect_mode="indexed", write_metadata=True, is_listener=True, color="white")) self.color_plot.overlays.append(LineInspector(component=self.color_plot, axis='index_y', inspect_mode="indexed", write_metadata=True, color="white", is_listener=True)) myrange = DataRange1D(low=amin(z), high=amax(z)) cmap=jet self.colormap = cmap(myrange) # Create a colorbar cbar_index_mapper = LinearMapper(range=myrange) self.colorbar = ColorBar(index_mapper=cbar_index_mapper, plot=self.color_plot, padding_top=self.color_plot.padding_top, padding_bottom=self.color_plot.padding_bottom, padding_right=40, resizable='v', width=30)#, ytitle="Magvec (mV)") #create horizontal line plot self.horiz_cross_plot = Plot(self.pd_horiz, resizable="h") self.horiz_cross_plot.height = 100 self.horiz_cross_plot.padding = 20 self.horiz_cross_plot.plot(("x", "horiz"))#, #line_style="dot") # self.cross_plot.plot(("scatter_index","scatter_value","scatter_color"), # type="cmap_scatter", # name="dot", # color_mapper=self._cmap(image_value_range), # marker="circle", # marker_size=8) self.horiz_cross_plot.index_range = self.color_plot.index_range.x_range #create vertical line plot self.vert_cross_plot = Plot(self.pd_vert, width = 140, orientation="v", resizable="v", padding=20, padding_bottom=160) self.vert_cross_plot.plot(("y", "vert"))#, # line_style="dot") # self.vert_cross_plot.xtitle="Magvec (mV)" # self.vertica_cross_plot.plot(("vertical_scatter_index", # "vertical_scatter_value", # "vertical_scatter_color"), # type="cmap_scatter", # name="dot", # color_mapper=self._cmap(image_value_range), # marker="circle", # marker_size=8) self.vert_cross_plot.index_range = self.color_plot.index_range.y_range # Create a container and add components self.container = HPlotContainer(padding=40, fill_padding=True, bgcolor = "white", use_backbuffer=False) inner_cont = VPlotContainer(padding=0, use_backbuffer=True) inner_cont.add(self.horiz_cross_plot) inner_cont.add(self.color_plot) self.container.add(self.colorbar) self.container.add(inner_cont) self.container.add(self.vert_cross_plot)
def __init__(self, link, plot_history_max=1000, dirname=''): super(BaselineView, self).__init__() self.log_file = None self.directory_name_b = dirname self.num_hyps = 0 self.last_hyp_update = 0 self.last_btime_update = 0 self.last_soln = None self.last_mode = 0 self.plot_data = ArrayPlotData(n_fixed=[0.0], e_fixed=[0.0], d_fixed=[0.0], n_float=[0.0], e_float=[0.0], d_float=[0.0], n_dgnss=[0.0], e_dgnss=[0.0], d_dgnss=[0.0], t=[0.0], ref_n=[0.0], ref_e=[0.0], ref_d=[0.0], cur_fixed_e=[], cur_fixed_n=[], cur_fixed_d=[], cur_float_e=[], cur_float_n=[], cur_float_d=[], cur_dgnss_e=[], cur_dgnss_n=[], cur_dgnss_d=[]) self.plot_history_max = plot_history_max self.n = np.zeros(plot_history_max) self.e = np.zeros(plot_history_max) self.d = np.zeros(plot_history_max) self.mode = np.zeros(plot_history_max) self.plot = Plot(self.plot_data) pts_float = self.plot.plot(('e_float', 'n_float'), type='scatter', color=color_dict[FLOAT_MODE], marker='dot', line_width=0.0, marker_size=1.0) pts_fixed = self.plot.plot( # noqa: F841 ('e_fixed', 'n_fixed'), type='scatter', color=color_dict[FIXED_MODE], marker='dot', line_width=0.0, marker_size=1.0) pts_dgnss = self.plot.plot( # noqa: F841 ('e_dgnss', 'n_dgnss'), type='scatter', color=color_dict[DGNSS_MODE], marker='dot', line_width=0.0, marker_size=1.0) ref = self.plot.plot(('ref_e', 'ref_n'), type='scatter', color='red', marker='plus', marker_size=5, line_width=1.5) cur_fixed = self.plot.plot(('cur_fixed_e', 'cur_fixed_n'), type='scatter', color=color_dict[FIXED_MODE], marker='plus', marker_size=5, line_width=1.5) cur_float = self.plot.plot(('cur_float_e', 'cur_float_n'), type='scatter', color=color_dict[FLOAT_MODE], marker='plus', marker_size=5, line_width=1.5) cur_dgnss = self.plot.plot(('cur_dgnss_e', 'cur_dgnss_n'), type='scatter', color=color_dict[DGNSS_MODE], marker='plus', line_width=1.5, marker_size=5) plot_labels = [' Base Position', 'DGPS', 'RTK Float', 'RTK Fixed'] plots_legend = dict( zip(plot_labels, [ref, cur_dgnss, cur_float, cur_fixed])) self.plot.legend.plots = plots_legend self.plot.legend.labels = plot_labels # sets order self.plot.legend.visible = True self.plot.index_axis.tick_label_position = 'inside' self.plot.index_axis.tick_label_color = 'gray' self.plot.index_axis.tick_color = 'gray' self.plot.index_axis.title = 'E (meters)' self.plot.index_axis.title_spacing = 5 self.plot.value_axis.tick_label_position = 'inside' self.plot.value_axis.tick_label_color = 'gray' self.plot.value_axis.tick_color = 'gray' self.plot.value_axis.title = 'N (meters)' self.plot.value_axis.title_spacing = 5 self.plot.padding = (25, 25, 25, 25) self.plot.tools.append(PanTool(self.plot)) zt = ZoomTool(self.plot, zoom_factor=1.1, tool_mode="box", always_on=False) self.plot.overlays.append(zt) self.week = None self.utc_time = None self.age_corrections = None self.heading = None self.nsec = 0 self.link = link self.link.add_callback( self.baseline_callback, [SBP_MSG_BASELINE_NED, SBP_MSG_BASELINE_NED_DEP_A]) self.link.add_callback(self.baseline_heading_callback, [SBP_MSG_BASELINE_HEADING]) self.link.add_callback(self.iar_state_callback, SBP_MSG_IAR_STATE) self.link.add_callback(self.gps_time_callback, [SBP_MSG_GPS_TIME, SBP_MSG_GPS_TIME_DEP_A]) self.link.add_callback(self.utc_time_callback, [SBP_MSG_UTC_TIME]) self.link.add_callback(self.age_corrections_callback, SBP_MSG_AGE_CORRECTIONS) call_repeatedly(0.2, self.solution_draw) self.python_console_cmds = {'baseline': self}
class SolutionView(HasTraits): python_console_cmds = Dict() # we need to doubleup on Lists to store the psuedo absolutes separately # without rewriting everything lats = List() lngs = List() alts = List() lats_psuedo_abs = List() lngs_psuedo_abs = List() alts_psuedo_abs = List() table_spp = List() table_psuedo_abs = List() dops_table = List() pos_table_spp = List() vel_table = List() plot = Instance(Plot) plot_data = Instance(ArrayPlotData) # Store plots we care about for legend running = Bool(True) zoomall = Bool(False) position_centered = Bool(False) clear_button = SVGButton(label='', tooltip='Clear', filename=os.path.join(os.path.dirname(__file__), 'images', 'iconic', 'x.svg'), width=16, height=16) zoomall_button = SVGButton(label='', tooltip='Zoom All', toggle=True, filename=os.path.join(os.path.dirname(__file__), 'images', 'iconic', 'fullscreen.svg'), width=16, height=16) center_button = SVGButton(label='', tooltip='Center on Solution', toggle=True, filename=os.path.join(os.path.dirname(__file__), 'images', 'iconic', 'target.svg'), width=16, height=16) paused_button = SVGButton( label='', tooltip='Pause', toggle_tooltip='Run', toggle=True, filename=os.path.join(os.path.dirname(__file__), 'images', 'iconic', 'pause.svg'), toggle_filename=os.path.join(os.path.dirname(__file__), 'images', 'iconic', 'play.svg'), width=16, height=16) traits_view = View( HSplit( Tabbed( VGroup(Item('', label='Single Point Position (SPP)', emphasized=True), Item('table_spp', style='readonly', editor=TabularEditor(adapter=SimpleAdapter()), show_label=False, width=0.3), label='Single Point Position'), VGroup(Item('', label='RTK Position', emphasized=True), Item('table_psuedo_abs', style='readonly', editor=TabularEditor(adapter=SimpleAdapter()), show_label=False, width=0.3), label='RTK Position')), VGroup( HGroup( Item('paused_button', show_label=False), Item('clear_button', show_label=False), Item('zoomall_button', show_label=False), Item('center_button', show_label=False), ), Item('plot', show_label=False, editor=ComponentEditor(bgcolor=(0.8, 0.8, 0.8))), ))) def _zoomall_button_fired(self): self.zoomall = not self.zoomall def _center_button_fired(self): self.position_centered = not self.position_centered def _paused_button_fired(self): self.running = not self.running def _clear_button_fired(self): self.lats = [] self.lngs = [] self.alts = [] self.lats_psuedo_abs = [] self.lngs_psuedo_abs = [] self.alts_psuedo_abs = [] self.plot_data.set_data('lat', []) self.plot_data.set_data('lng', []) self.plot_data.set_data('alt', []) self.plot_data.set_data('t', []) self.plot_data.set_data('lat_ps', []) self.plot_data.set_data('lng_ps', []) self.plot_data.set_data('alt_ps', []) self.plot_data.set_data('t_ps', []) def _pos_llh_callback(self, sbp_msg, **metadata): # Updating an ArrayPlotData isn't thread safe (see chaco issue #9), so # actually perform the update in the UI thread. if self.running: GUI.invoke_later(self.pos_llh_callback, sbp_msg) def update_table(self): self._table_list = self.table_spp.items() def pos_llh_callback(self, sbp_msg, **metadata): soln = MsgPosLLH(sbp_msg) masked_flag = soln.flags & 0x7 if masked_flag == 0: psuedo_absolutes = False else: psuedo_absolutes = True pos_table = [] if self.log_file is None: self.log_file = open( time.strftime("position_log_%Y%m%d-%H%M%S.csv"), 'w') self.log_file.write( "time,latitude(degrees),longitude(degrees),altitude(meters),n_sats,flags\n" ) tow = soln.tow * 1e-3 if self.nsec is not None: tow += self.nsec * 1e-9 if self.week is not None: t = datetime.datetime(1980, 1, 6) + \ datetime.timedelta(weeks=self.week) + \ datetime.timedelta(seconds=tow) pos_table.append(('GPS Time', t)) pos_table.append(('GPS Week', str(self.week))) self.log_file.write('%s,%.10f,%.10f,%.4f,%d,%d\n' % (str(t), soln.lat, soln.lon, soln.height, soln.n_sats, soln.flags)) self.log_file.flush() pos_table.append(('GPS ToW', tow)) pos_table.append(('Num. sats', soln.n_sats)) pos_table.append(('Lat', soln.lat)) pos_table.append(('Lng', soln.lon)) pos_table.append(('Alt', soln.height)) pos_table.append(('Flags', '0x%02x' % soln.flags)) if (soln.flags & 0xff) == 0: pos_table.append(('Mode', 'SPP (single point position)')) elif (soln.flags & 0xff) == 1: pos_table.append(('Mode', 'Fixed RTK')) elif (soln.flags & 0xff) == 2: pos_table.append(('Mode', 'Float RTK')) else: pos_table.append(('Mode', 'Unknown')) if psuedo_absolutes: # setup_plot variables self.lats_psuedo_abs.append(soln.lat) self.lngs_psuedo_abs.append(soln.lon) self.alts_psuedo_abs.append(soln.height) self.lats_psuedo_abs = self.lats_psuedo_abs[-1000:] self.lngs_psuedo_abs = self.lngs_psuedo_abs[-1000:] self.alts_psuedo_abs = self.alts_psuedo_abs[-1000:] self.plot_data.set_data('lat_ps', self.lats_psuedo_abs) self.plot_data.set_data('lng_ps', self.lngs_psuedo_abs) self.plot_data.set_data('alt_ps', self.alts_psuedo_abs) self.plot_data.set_data('cur_lat_ps', [soln.lat]) self.plot_data.set_data('cur_lng_ps', [soln.lon]) t_psuedo_abs = range(len(self.lats)) self.plot_data.set_data('t', t) self.plot_data.set_data('t_ps', t_psuedo_abs) # set-up table variables self.table_psuedo_abs = pos_table else: # setup_plot variables self.lats.append(soln.lat) self.lngs.append(soln.lon) self.alts.append(soln.height) self.lats = self.lats[-1000:] self.lngs = self.lngs[-1000:] self.alts = self.alts[-1000:] self.plot_data.set_data('lat', self.lats) self.plot_data.set_data('lng', self.lngs) self.plot_data.set_data('alt', self.alts) self.plot_data.set_data('cur_lat', [soln.lat]) self.plot_data.set_data('cur_lng', [soln.lon]) t = range(len(self.lats)) self.plot_data.set_data('t', t) # set-up table variables self.pos_table_spp = pos_table self.table_spp = self.pos_table_spp + self.vel_table + self.dops_table # TODO: figure out how to center the graph now that we have two separate messages # when we selectivtely send only SPP, the centering function won't work anymore if self.position_centered: d = (self.plot.index_range.high - self.plot.index_range.low) / 2. self.plot.index_range.set_bounds(soln.lon - d, soln.lon + d) d = (self.plot.value_range.high - self.plot.value_range.low) / 2. self.plot.value_range.set_bounds(soln.lat - d, soln.lat + d) if self.zoomall: plot_square_axes(self.plot, 'lng', 'lat') def dops_callback(self, sbp_msg, **metadata): dops = MsgDops(sbp_msg) self.dops_table = [('PDOP', '%.1f' % (dops.pdop * 0.01)), ('GDOP', '%.1f' % (dops.gdop * 0.01)), ('TDOP', '%.1f' % (dops.tdop * 0.01)), ('HDOP', '%.1f' % (dops.hdop * 0.01)), ('VDOP', '%.1f' % (dops.vdop * 0.01))] self.table_spp = self.pos_table_spp + self.vel_table + self.dops_table def vel_ned_callback(self, sbp_msg, **metadata): vel_ned = MsgVelNED(sbp_msg) if self.vel_log_file is None: self.vel_log_file = open( time.strftime("velocity_log_%Y%m%d-%H%M%S.csv"), 'w') self.vel_log_file.write( 'time,north(m/s),east(m/s),down(m/s),speed(m/s),num_sats\n') tow = vel_ned.tow * 1e-3 if self.nsec is not None: tow += self.nsec * 1e-9 if self.week is not None: t = datetime.datetime(1980, 1, 6) + \ datetime.timedelta(weeks=self.week) + \ datetime.timedelta(seconds=tow) self.vel_log_file.write( '%s,%.6f,%.6f,%.6f,%.6f,%d\n' % (str(t), vel_ned.n * 1e-3, vel_ned.e * 1e-3, vel_ned.d * 1e-3, math.sqrt(vel_ned.n * vel_ned.n + vel_ned.e * vel_ned.e) * 1e-3, vel_ned.n_sats)) self.vel_log_file.flush() self.vel_table = [ ('Vel. N', '% 8.4f' % (vel_ned.n * 1e-3)), ('Vel. E', '% 8.4f' % (vel_ned.e * 1e-3)), ('Vel. D', '% 8.4f' % (vel_ned.d * 1e-3)), ] self.table_spp = self.pos_table_spp + self.vel_table + self.dops_table def gps_time_callback(self, sbp_msg, **metadata): self.week = MsgGPSTime(sbp_msg).wn self.nsec = MsgGPSTime(sbp_msg).ns def __init__(self, link): super(SolutionView, self).__init__() self.log_file = None self.vel_log_file = None self.plot_data = ArrayPlotData(lat=[], lng=[], alt=[], t=[], cur_lat=[], cur_lng=[], cur_lat_ps=[], cur_lng_ps=[], lat_ps=[], lng_ps=[], alt_ps=[], t_ps=[]) self.plot = Plot(self.plot_data) # 1000 point buffer self.plot.plot(('lng', 'lat'), type='line', name='', color=(0, 0, 0.9, 0.1)) self.plot.plot(('lng', 'lat'), type='scatter', name='', color='blue', marker='dot', line_width=0.0, marker_size=1.0) self.plot.plot(('lng_ps', 'lat_ps'), type='line', name='', color=(1, 0.4, 0, 0.1)) self.plot.plot(('lng_ps', 'lat_ps'), type='scatter', name='', color='orange', marker='diamond', line_width=0.0, marker_size=1.0) # current values spp = self.plot.plot(('cur_lng', 'cur_lat'), type='scatter', name='SPP', color='blue', marker='plus', line_width=1.5, marker_size=5.0) rtk = self.plot.plot(('cur_lng_ps', 'cur_lat_ps'), type='scatter', name='RTK', color='orange', marker='plus', line_width=1.5, marker_size=5.0) plot_labels = ['SPP', 'RTK'] plots_legend = dict(zip(plot_labels, [spp, rtk])) self.plot.legend.plots = plots_legend self.plot.legend.visible = True self.plot.index_axis.tick_label_position = 'inside' self.plot.index_axis.tick_label_color = 'gray' self.plot.index_axis.tick_color = 'gray' self.plot.index_axis.title = 'Longitude (degrees)' self.plot.index_axis.title_spacing = 5 self.plot.value_axis.tick_label_position = 'inside' self.plot.value_axis.tick_label_color = 'gray' self.plot.value_axis.tick_color = 'gray' self.plot.value_axis.title = 'Latitude (degrees)' self.plot.value_axis.title_spacing = 5 self.plot.padding = (25, 25, 25, 25) self.plot.tools.append(PanTool(self.plot)) zt = ZoomTool(self.plot, zoom_factor=1.1, tool_mode="box", always_on=False) self.plot.overlays.append(zt) self.link = link self.link.add_callback(self._pos_llh_callback, SBP_MSG_POS_LLH) self.link.add_callback(self.vel_ned_callback, SBP_MSG_VEL_NED) self.link.add_callback(self.dops_callback, SBP_MSG_DOPS) self.link.add_callback(self.gps_time_callback, SBP_MSG_GPS_TIME) self.week = None self.nsec = 0 self.python_console_cmds = { 'solution': self, }
class BaselineView(HasTraits): python_console_cmds = Dict() plot = Instance(Plot) plot_data = Instance(ArrayPlotData) running = Bool(True) zoomall = Bool(False) clear_button = SVGButton(label='', tooltip='Clear', filename=os.path.join(determine_path(), 'images', 'iconic', 'x.svg'), width=16, height=16) zoomall_button = SVGButton(label='', tooltip='Zoom All', toggle=True, filename=os.path.join(determine_path(), 'images', 'iconic', 'fullscreen.svg'), width=16, height=16) paused_button = SVGButton(label='', tooltip='Pause', toggle_tooltip='Run', toggle=True, filename=os.path.join(determine_path(), 'images', 'iconic', 'pause.svg'), toggle_filename=os.path.join( determine_path(), 'images', 'iconic', 'play.svg'), width=16, height=16) position_threshold = Str() depth_threshold = Str() time_threshold = Str() focused_dev = Str dev_all_list = List(['All', 'Preset']) traits_view = View( HSplit( VGroup( HGroup( Item('paused_button', show_label=False), Item('clear_button', show_label=False), Item('zoomall_button', show_label=False), Item('focused_dev', editor=EnumEditor(name='dev_all_list'), label=u'焦点'), Spring(), HGroup( Item('position_threshold', editor=TextEditor(auto_set=False, enter_set=True), label=u'位置阈值'), Item('depth_threshold', editor=TextEditor(), label=u'深度阈值'), Item('time_threshold', editor=TextEditor(), label=u'时间阈值'), )), Item( 'plot', show_label=False, editor=ComponentEditor(bgcolor=(0.8, 0.8, 0.8)), ))), ) def _position_threshold_changed(self): try: if int(self.position_threshold) < 0 or int( self.position_threshold) > 1e6: self.position_threshold = str(0) except: self.position_threshold = str(0) self.settings_yaml.set_threshold_field('position', int(self.position_threshold)) self.settings_yaml.dump() def _depth_threshold_changed(self): try: if int(self.depth_threshold) < 0 or int( self.depth_threshold) > self.plot_history_max: self.plot_history_max = str(0) except: self.plot_history_max = str(0) self.settings_yaml.set_threshold_field('depth', int(self.depth_threshold)) self.settings_yaml.dump() def _time_threshold_changed(self): try: if int(self.time_threshold) < 0: self.time_threshold = str(0) except: self.time_threshold = str(0) self.settings_yaml.set_threshold_field('time', int(self.time_threshold)) self.settings_yaml.dump() def _focused_dev_changed(self): self.zoom_once = True def _zoomall_button_fired(self): self.zoomall = not self.zoomall def _paused_button_fired(self): self.running = not self.running def _clear_button_fired(self): self.neds[:] = np.NAN self.fixeds[:] = False self.devs[:] = 0 self.times[:] = 0 self.plot_data.set_data('n_fixed', []) self.plot_data.set_data('e_fixed', []) self.plot_data.set_data('d_fixed', []) self.plot_data.set_data('n_float', []) self.plot_data.set_data('e_float', []) self.plot_data.set_data('d_float', []) self.plot_data.set_data('n_satisfied', []) self.plot_data.set_data('e_satisfied', []) self.plot_data.set_data('n_focused', []) self.plot_data.set_data('e_focused', []) self.plot_data.set_data('t', []) def _baseline_callback_ned(self, sbp_msg, **metadata): # Updating an ArrayPlotData isn't thread safe (see chaco issue #9), so # actually perform the update in the UI thread. if self.running: #GUI.invoke_later(self.baseline_callback, sbp_msg) soln = MsgBaselineNED(sbp_msg) GUI.invoke_later(self.baseline_callback, soln) cnt = self.cnt % 4 fake_sbp_msg = copy.copy(soln) if cnt == 3: fake_sbp_msg.e = 217371 fake_sbp_msg.n = 100837 - (cnt + 1) * 10e3 else: fake_sbp_msg.e = 217371 + cnt * 20e3 fake_sbp_msg.n = 100837 - cnt * 20e3 fake_sbp_msg.sender = 100 + cnt fake_sbp_msg.flags = cnt soln = fake_sbp_msg self.cnt += 1 GUI.invoke_later(self.baseline_callback, soln) # _threshold_satisfied()函数计算需要优化 # 或者保持数据发送频率小于2(/s) time.sleep(0.5) def baseline_callback(self, sbp_msg): #soln = MsgBaselineNED(sbp_msg) soln = sbp_msg soln.n = soln.n * 1e-3 soln.e = soln.e * 1e-3 soln.d = soln.d * 1e-3 dist = np.sqrt(soln.n**2 + soln.e**2 + soln.d**2) tow = soln.tow * 1e-3 if self.nsec is not None: tow += self.nsec * 1e-9 #row_data = [soln.sender, soln.n, soln.e, soln.d, soln.n_sats, soln.flags, soln.depth] row_data = [ soln.sender, soln.n, soln.e, soln.d, soln.n_sats, soln.flags ] try: key = int(row_data[0]) self.data_dict[key] = row_data except: pass self.utils.setDataViewTable(self.data_dict) if soln.sender not in self.dev_list: self.dev_list.append(soln.sender) self.dev_all_list.append(str(soln.sender)) # Rotate array, deleting oldest entries to maintain # no more than N in plot self.neds[1:] = self.neds[:-1] self.fixeds[1:] = self.fixeds[:-1] self.devs[1:] = self.devs[:-1] self.times[1:] = self.times[:-1] # Insert latest position self.neds[0][:] = [soln.n, soln.e, soln.d] self.fixeds[0] = (soln.flags & 1) == 1 self.devs[0] = int(soln.sender) self.times[0] = int(time.time()) neds_all = [] neds_fixed = [] neds_float = [] neds_satisfied = [] neds_unsatisfied = [] devs = np.unique(self.devs) if devs[0] == 0: devs = devs[1:] for dev in devs: is_dev = np.equal(dev, self.devs) neds_all.append(self.neds[is_dev][0]) try: neds_fixed.append(self.neds[np.logical_and( is_dev, self.fixeds)][0]) except: pass try: neds_float.append(self.neds[np.logical_and( is_dev, np.logical_not(self.fixeds))][0]) except: pass position_satisfied, depth_satisfied, time_satisfied = self._threshold_satisfied( ) is_satisfied = np.logical_and(position_satisfied, depth_satisfied, time_satisfied) try: neds_satisfied.append(self.neds[np.logical_and( is_dev, is_satisfied)][0]) except: pass try: neds_unsatisfied.append(self.neds[np.logical_and( is_dev, np.logical_not(is_satisfied))][0]) except: pass neds_all = np.array(neds_all) neds_fixed = np.array(neds_fixed) neds_float = np.array(neds_float) neds_satisfied = np.array(neds_satisfied) neds_unsatisfied = np.array(neds_unsatisfied) self.neds_all = neds_all self.neds_satisfied = neds_satisfied self.neds_unsatisfied = neds_unsatisfied neds_focused = np.empty((0, 3)) if self.focused_dev == '': pass elif self.focused_dev == 'All': neds_focused = neds_all elif self.focused_dev != 'Preset': neds_focused = np.array( [self.neds[np.equal(self.devs, int(self.focused_dev))][0]]) #if not all(map(any, np.isnan(neds_fixed))): if len(neds_fixed) > 0: self.plot_data.set_data('n_fixed', neds_fixed.T[0]) self.plot_data.set_data('e_fixed', neds_fixed.T[1]) self.plot_data.set_data('d_fixed', neds_fixed.T[2]) #if not all(map(any, np.isnan(neds_float))): if len(neds_float) > 0: self.plot_data.set_data('n_float', neds_float.T[0]) self.plot_data.set_data('e_float', neds_float.T[1]) self.plot_data.set_data('d_float', neds_float.T[2]) if len(neds_satisfied) > 0: self.plot_data.set_data('n_satisfied', neds_satisfied.T[0]) self.plot_data.set_data('e_satisfied', neds_satisfied.T[1]) if len(neds_unsatisfied) > 0: self.plot_data.set_data('n_unsatisfied', neds_unsatisfied.T[0]) self.plot_data.set_data('e_unsatisfied', neds_unsatisfied.T[1]) if len(self.presets) > 0: self.plot_data.set_data('n_preset', self.presets['n']) self.plot_data.set_data('e_preset', self.presets['e']) if len(neds_focused) > 0: self.plot_data.set_data('n_focused', neds_focused.T[0]) self.plot_data.set_data('e_focused', neds_focused.T[1]) if self.zoomall: self._zoomall() if self.zoom_once: if self.focused_dev == 'All': self._zoomall() elif self.focused_dev == 'Preset': plot_square_axes(self.plot, 'e_preset', 'n_preset') else: plot_square_axes(self.plot, 'e_focused', 'n_focused') self.zoom_once = False # 计算阈值,函数功能待测试 def _threshold_satisfied(self): position_satisfieds = np.zeros(self.plot_history_max, dtype=bool) depth_satisfieds = np.ones(self.plot_history_max, dtype=bool) time_satisfieds = np.ones(self.plot_history_max, dtype=bool) devs = np.unique(self.devs) for dev in devs: dev_neds = self.neds[np.equal(self.devs, dev)] ned_mean = map(np.mean, zip(*dev_neds)) dn = ned_mean[0] - self.presets['n'] de = ned_mean[1] - self.presets['e'] d = np.sqrt(np.add(np.square(dn), np.square(de))) dmin = np.min(d) if dmin < int(self.position_threshold): position_satisfieds[np.equal(dev, self.devs)] = True ne_depth = self.neds[0:int(self.depth_threshold)] for ned in ne_depth: dn = ned[0] - self.presets['n'] de = ned[1] - self.presets['e'] d = np.sqrt(np.add(np.square(dn), np.square(de))) dmin = np.min(d) if dmin > int(self.position_threshold): depth_satisfieds[np.equal(dev, self.devs)] = False break cur_time = time.time() for dev, t, ned in zip(self.devs, self.times, self.neds): dt = cur_time - t if dt > int(self.time_threshold): break dn = ned[0] - self.presets['n'] de = ned[1] - self.presets['e'] d = np.sqrt(np.add(np.square(dn), np.square(de))) dmin = np.min(d) if dmin > int(self.position_threshold): time_satisfieds[np.equal(dev, self.devs)] = False return (position_satisfieds, depth_satisfieds, time_satisfieds) def _zoomall(self): plot_square_axes(self.plot, ('e_fixed', 'e_float', 'e_preset'), ('n_fixed', 'n_float', 'n_preset')) def _read_preset_points(self, filename='preset.csv'): preset_points = {} px = [] py = [] try: if os.path.isfile(filename): path_to_file = filename else: path_to_file = os.path.join(determine_path(), filename) f = open(path_to_file, 'r') for i in f.readlines(): xy = i.split(',') if len(xy) < 2: continue try: x = float(xy[0]) * 1e-3 y = float(xy[1]) * 1e-3 px.append(x) py.append(y) except: continue except: pass preset_points['e'] = px preset_points['n'] = py return preset_points def set_utils(self, utils): self.utils = utils def __init__(self, link, plot_history_max=1000): super(BaselineView, self).__init__() self.plot_data = ArrayPlotData(n_fixed=[0.0], e_fixed=[0.0], d_fixed=[0.0], n_float=[0.0], e_float=[0.0], d_float=[0.0], n_satisfied=[0.0], e_satisfied=[0.0], n_unsatisfied=[0.0], e_unsatisfied=[0.0], n_focused=[0.0], e_focused=[0.0], t=[0.0], e_preset=[], n_preset=[]) self.plot_history_max = plot_history_max self.neds = np.empty((plot_history_max, 3)) self.neds[:] = np.NAN self.fixeds = np.zeros(plot_history_max, dtype=bool) self.devs = np.zeros(plot_history_max) self.times = np.zeros(plot_history_max) self.plot = Plot(self.plot_data) color_float = (0.5, 0.5, 1.0) color_fixed = 'orange' color_satisfied = (0.3, 1.0, 0.0) pts_float = self.plot.plot(('e_float', 'n_float'), type='scatter', color=color_float, marker='plus', line_width=2.0, marker_size=8.0) pts_fixed = self.plot.plot(('e_fixed', 'n_fixed'), type='scatter', color=color_fixed, marker='plus', line_width=2.0, marker_size=8.0) threshold_satisfied = self.plot.plot(('e_satisfied', 'n_satisfied'), type='scatter', color=color_satisfied, marker='dot', line_width=0.0, marker_size=4.5) threshold_unsatisfied = self.plot.plot( ('e_unsatisfied', 'n_unsatisfied'), type='scatter', color='red', marker='dot', line_width=0.0, marker_size=4.5) preset = self.plot.plot(('e_preset', 'n_preset'), type='scatter', color='black', marker='plus', marker_size=1.5, line_width=0.0) pts_focused = self.plot.plot(('e_focused', 'n_focused'), type='scatter', color='black', marker='dot', line_width=0.0, marker_size=0.0) #plot_labels = ['RTK Fixed','RTK Float'] #plots_legend = dict(zip(plot_labels, [pts_fixed, pts_float])) #self.plot.legend.plots = plots_legend #self.plot.legend.visible = True self.plot.legend.visible = False self.plot.index_axis.tick_label_position = 'inside' self.plot.index_axis.tick_label_color = 'gray' self.plot.index_axis.tick_color = 'gray' self.plot.index_axis.title = 'E (meters)' self.plot.index_axis.title_spacing = 5 self.plot.value_axis.tick_label_position = 'inside' self.plot.value_axis.tick_label_color = 'gray' self.plot.value_axis.tick_color = 'gray' self.plot.value_axis.title = 'N (meters)' self.plot.value_axis.title_spacing = 5 self.plot.padding = (25, 25, 25, 25) self.plot.tools.append(PanTool(self.plot)) zt = ZoomTool(self.plot, zoom_factor=1.1, tool_mode="box", always_on=False) self.plot.overlays.append(zt) self.week = None self.nsec = 0 self.link = link self.link.add_callback(self._baseline_callback_ned, SBP_MSG_BASELINE_NED) self.cnt = 0 self.dev_list = [] self.data_dict = {} self.presets = self._read_preset_points() self.settings_yaml = SettingsList() self.position_threshold = str( self.settings_yaml.get_threshold_field('position')) self.depth_threshold = str( self.settings_yaml.get_threshold_field('depth')) self.time_threshold = str( self.settings_yaml.get_threshold_field('time')) self.zoom_once = False self.python_console_cmds = {'baseline': self}
class BaselineView(HasTraits): # This mapping should match the flag definitions in libsbp for # the MsgBaselineNED message. While this isn't strictly necessary # it helps avoid confusion python_console_cmds = Dict() table = List() logging_b = Bool(False) directory_name_b = File plot = Instance(Plot) plot_data = Instance(ArrayPlotData) running = Bool(True) zoomall = Bool(False) position_centered = Bool(False) clear_button = SVGButton(label='', tooltip='Clear', filename=os.path.join(determine_path(), 'images', 'iconic', 'x.svg'), width=16, height=16) zoomall_button = SVGButton(label='', tooltip='Zoom All', toggle=True, filename=os.path.join(determine_path(), 'images', 'iconic', 'fullscreen.svg'), width=16, height=16) center_button = SVGButton(label='', tooltip='Center on Baseline', toggle=True, filename=os.path.join(determine_path(), 'images', 'iconic', 'target.svg'), width=16, height=16) paused_button = SVGButton(label='', tooltip='Pause', toggle_tooltip='Run', toggle=True, filename=os.path.join(determine_path(), 'images', 'iconic', 'pause.svg'), toggle_filename=os.path.join( determine_path(), 'images', 'iconic', 'play.svg'), width=16, height=16) reset_button = Button(label='Reset Filters') traits_view = View( HSplit( Item('table', style='readonly', editor=TabularEditor(adapter=SimpleAdapter()), show_label=False, width=0.3), VGroup( HGroup( Item('paused_button', show_label=False), Item('clear_button', show_label=False), Item('zoomall_button', show_label=False), Item('center_button', show_label=False), Item('reset_button', show_label=False), ), Item( 'plot', show_label=False, editor=ComponentEditor(bgcolor=(0.8, 0.8, 0.8)), )))) def _zoomall_button_fired(self): self.zoomall = not self.zoomall def _center_button_fired(self): self.position_centered = not self.position_centered def _paused_button_fired(self): self.running = not self.running def _reset_button_fired(self): self.link(MsgResetFilters(filter=0)) def _reset_remove_current(self): self.plot_data.set_data('cur_fixed_n', []) self.plot_data.set_data('cur_fixed_e', []) self.plot_data.set_data('cur_fixed_d', []) self.plot_data.set_data('cur_float_n', []) self.plot_data.set_data('cur_float_e', []) self.plot_data.set_data('cur_float_d', []) self.plot_data.set_data('cur_dgnss_n', []) self.plot_data.set_data('cur_dgnss_e', []) self.plot_data.set_data('cur_dgnss_d', []) def _clear_history(self): self.plot_data.set_data('n_fixed', []) self.plot_data.set_data('e_fixed', []) self.plot_data.set_data('d_fixed', []) self.plot_data.set_data('n_float', []) self.plot_data.set_data('e_float', []) self.plot_data.set_data('d_float', []) self.plot_data.set_data('n_dgnss', []) self.plot_data.set_data('e_dgnss', []) self.plot_data.set_data('d_dgnss', []) def _clear_button_fired(self): self.n[:] = np.NAN self.e[:] = np.NAN self.d[:] = np.NAN self.mode[:] = np.NAN self.plot_data.set_data('t', []) self._clear_history() self._reset_remove_current() def iar_state_callback(self, sbp_msg, **metadata): self.num_hyps = sbp_msg.num_hyps self.last_hyp_update = time.time() def age_corrections_callback(self, sbp_msg, **metadata): age_msg = MsgAgeCorrections(sbp_msg) if age_msg.age != 0xFFFF: self.age_corrections = age_msg.age / 10.0 else: self.age_corrections = None def gps_time_callback(self, sbp_msg, **metadata): if sbp_msg.msg_type == SBP_MSG_GPS_TIME_DEP_A: time_msg = MsgGPSTimeDepA(sbp_msg) flags = 1 elif sbp_msg.msg_type == SBP_MSG_GPS_TIME: time_msg = MsgGPSTime(sbp_msg) flags = time_msg.flags if flags != 0: self.week = time_msg.wn self.nsec = time_msg.ns_residual def utc_time_callback(self, sbp_msg, **metadata): tmsg = MsgUtcTime(sbp_msg) seconds = math.floor(tmsg.seconds) microseconds = int(tmsg.ns / 1000.00) if tmsg.flags & 0x1 == 1: dt = datetime.datetime(tmsg.year, tmsg.month, tmsg.day, tmsg.hours, tmsg.minutes, tmsg.seconds, microseconds) self.utc_time = dt self.utc_time_flags = tmsg.flags if (tmsg.flags >> 3) & 0x3 == 0: self.utc_source = "Factory Default" elif (tmsg.flags >> 3) & 0x3 == 1: self.utc_source = "Non Volatile Memory" elif (tmsg.flags >> 3) & 0x3 == 2: self.utc_source = "Decoded this Session" else: self.utc_source = "Unknown" else: self.utc_time = None self.utc_source = None def baseline_heading_callback(self, sbp_msg, **metadata): headingMsg = MsgBaselineHeading(sbp_msg) if headingMsg.flags & 0x7 != 0: self.heading = headingMsg.heading * 1e-3 else: self.heading = None def baseline_callback(self, sbp_msg, **metadata): soln = MsgBaselineNEDDepA(sbp_msg) self.last_soln = soln table = [] soln.n = soln.n * 1e-3 soln.e = soln.e * 1e-3 soln.d = soln.d * 1e-3 soln.h_accuracy = soln.h_accuracy * 1e-3 soln.v_accuracy = soln.v_accuracy * 1e-3 dist = np.sqrt(soln.n**2 + soln.e**2 + soln.d**2) tow = soln.tow * 1e-3 if self.nsec is not None: tow += self.nsec * 1e-9 ((tloc, secloc), (tgps, secgps)) = log_time_strings(self.week, tow) if self.utc_time is not None: ((tutc, secutc)) = datetime_2_str(self.utc_time) if self.directory_name_b == '': filepath = time.strftime("baseline_log_%Y%m%d-%H%M%S.csv") else: filepath = os.path.join( self.directory_name_b, time.strftime("baseline_log_%Y%m%d-%H%M%S.csv")) if not self.logging_b: self.log_file = None if self.logging_b: if self.log_file is None: self.log_file = sopen(filepath, 'w') self.log_file.write( 'pc_time,gps_time,tow(msec),north(meters),east(meters),down(meters),h_accuracy(meters),v_accuracy(meters),' 'distance(meters),num_sats,flags,num_hypothesis\n') log_str_gps = '' if tgps != '' and secgps != 0: log_str_gps = "{0}:{1:06.6f}".format(tgps, float(secgps)) self.log_file.write( '%s,%s,%.3f,%.4f,%.4f,%.4f,%.4f,%.4f,%.4f,%d,%d,%d\n' % ("{0}:{1:06.6f}".format(tloc, float(secloc)), log_str_gps, tow, soln.n, soln.e, soln.d, soln.h_accuracy, soln.v_accuracy, dist, soln.n_sats, soln.flags, self.num_hyps)) self.log_file.flush() self.last_mode = get_mode(soln) if self.last_mode < 1: table.append(('GPS Week', EMPTY_STR)) table.append(('GPS TOW', EMPTY_STR)) table.append(('GPS Time', EMPTY_STR)) table.append(('UTC Time', EMPTY_STR)) table.append(('UTC Src', EMPTY_STR)) table.append(('N', EMPTY_STR)) table.append(('E', EMPTY_STR)) table.append(('D', EMPTY_STR)) table.append(('Horiz Acc', EMPTY_STR)) table.append(('Vert Acc', EMPTY_STR)) table.append(('Dist.', EMPTY_STR)) table.append(('Sats Used', EMPTY_STR)) table.append(('Flags', EMPTY_STR)) table.append(('Mode', EMPTY_STR)) else: self.last_btime_update = time.time() if self.week is not None: table.append(('GPS Week', str(self.week))) table.append(('GPS TOW', "{:.3f}".format(tow))) if self.week is not None: table.append( ('GPS Time', "{0}:{1:06.3f}".format(tgps, float(secgps)))) if self.utc_time is not None: table.append( ('UTC Time', "{0}:{1:06.3f}".format(tutc, float(secutc)))) table.append(('UTC Src', self.utc_source)) table.append(('N', soln.n)) table.append(('E', soln.e)) table.append(('D', soln.d)) table.append(('Horiz Acc', soln.h_accuracy)) table.append(('Vert Acc', soln.v_accuracy)) table.append(('Dist.', "{0:.3f}".format(dist))) table.append(('Sats Used', soln.n_sats)) table.append(('Flags', '0x%02x' % soln.flags)) table.append(('Mode', mode_dict[self.last_mode])) if self.heading is not None: table.append(('Heading', self.heading)) if self.age_corrections is not None: table.append(('Corr. Age [s]', self.age_corrections)) self.table = table # Rotate array, deleting oldest entries to maintain # no more than N in plot self.n[1:] = self.n[:-1] self.e[1:] = self.e[:-1] self.d[1:] = self.d[:-1] self.mode[1:] = self.mode[:-1] # Insert latest position if self.last_mode > 1: self.n[0], self.e[0], self.d[0] = soln.n, soln.e, soln.d else: self.n[0], self.e[0], self.d[0] = [np.NAN, np.NAN, np.NAN] self.mode[0] = self.last_mode def solution_draw(self): if self.running: GUI.invoke_later(self._solution_draw) def _solution_draw(self): self._clear_history() soln = self.last_soln if np.any(self.mode): float_indexer = (self.mode == FLOAT_MODE) fixed_indexer = (self.mode == FIXED_MODE) dgnss_indexer = (self.mode == DGNSS_MODE) if np.any(fixed_indexer): self.plot_data.set_data('n_fixed', self.n[fixed_indexer]) self.plot_data.set_data('e_fixed', self.e[fixed_indexer]) self.plot_data.set_data('d_fixed', self.d[fixed_indexer]) if np.any(float_indexer): self.plot_data.set_data('n_float', self.n[float_indexer]) self.plot_data.set_data('e_float', self.e[float_indexer]) self.plot_data.set_data('d_float', self.d[float_indexer]) if np.any(dgnss_indexer): self.plot_data.set_data('n_dgnss', self.n[dgnss_indexer]) self.plot_data.set_data('e_dgnss', self.e[dgnss_indexer]) self.plot_data.set_data('d_dgnss', self.d[dgnss_indexer]) # Update our last solution icon if self.last_mode == FIXED_MODE: self._reset_remove_current() self.plot_data.set_data('cur_fixed_n', [soln.n]) self.plot_data.set_data('cur_fixed_e', [soln.e]) self.plot_data.set_data('cur_fixed_d', [soln.d]) elif self.last_mode == FLOAT_MODE: self._reset_remove_current() self.plot_data.set_data('cur_float_n', [soln.n]) self.plot_data.set_data('cur_float_e', [soln.e]) self.plot_data.set_data('cur_float_d', [soln.d]) elif self.last_mode == DGNSS_MODE: self._reset_remove_current() self.plot_data.set_data('cur_dgnss_n', [soln.n]) self.plot_data.set_data('cur_dgnss_e', [soln.e]) self.plot_data.set_data('cur_dgnss_d', [soln.d]) else: pass # make the zoomall win over the position centered button # position centered button has no effect when zoom all enabled if not self.zoomall and self.position_centered: d = (self.plot.index_range.high - self.plot.index_range.low) / 2. self.plot.index_range.set_bounds(soln.e - d, soln.e + d) d = (self.plot.value_range.high - self.plot.value_range.low) / 2. self.plot.value_range.set_bounds(soln.n - d, soln.n + d) if self.zoomall: plot_square_axes(self.plot, ('e_fixed', 'e_float', 'e_dgnss'), ('n_fixed', 'n_float', 'n_dgnss')) def __init__(self, link, plot_history_max=1000, dirname=''): super(BaselineView, self).__init__() self.log_file = None self.directory_name_b = dirname self.num_hyps = 0 self.last_hyp_update = 0 self.last_btime_update = 0 self.last_soln = None self.last_mode = 0 self.plot_data = ArrayPlotData(n_fixed=[0.0], e_fixed=[0.0], d_fixed=[0.0], n_float=[0.0], e_float=[0.0], d_float=[0.0], n_dgnss=[0.0], e_dgnss=[0.0], d_dgnss=[0.0], t=[0.0], ref_n=[0.0], ref_e=[0.0], ref_d=[0.0], cur_fixed_e=[], cur_fixed_n=[], cur_fixed_d=[], cur_float_e=[], cur_float_n=[], cur_float_d=[], cur_dgnss_e=[], cur_dgnss_n=[], cur_dgnss_d=[]) self.plot_history_max = plot_history_max self.n = np.zeros(plot_history_max) self.e = np.zeros(plot_history_max) self.d = np.zeros(plot_history_max) self.mode = np.zeros(plot_history_max) self.plot = Plot(self.plot_data) pts_float = self.plot.plot(('e_float', 'n_float'), type='scatter', color=color_dict[FLOAT_MODE], marker='dot', line_width=0.0, marker_size=1.0) pts_fixed = self.plot.plot( # noqa: F841 ('e_fixed', 'n_fixed'), type='scatter', color=color_dict[FIXED_MODE], marker='dot', line_width=0.0, marker_size=1.0) pts_dgnss = self.plot.plot( # noqa: F841 ('e_dgnss', 'n_dgnss'), type='scatter', color=color_dict[DGNSS_MODE], marker='dot', line_width=0.0, marker_size=1.0) ref = self.plot.plot(('ref_e', 'ref_n'), type='scatter', color='red', marker='plus', marker_size=5, line_width=1.5) cur_fixed = self.plot.plot(('cur_fixed_e', 'cur_fixed_n'), type='scatter', color=color_dict[FIXED_MODE], marker='plus', marker_size=5, line_width=1.5) cur_float = self.plot.plot(('cur_float_e', 'cur_float_n'), type='scatter', color=color_dict[FLOAT_MODE], marker='plus', marker_size=5, line_width=1.5) cur_dgnss = self.plot.plot(('cur_dgnss_e', 'cur_dgnss_n'), type='scatter', color=color_dict[DGNSS_MODE], marker='plus', line_width=1.5, marker_size=5) plot_labels = [' Base Position', 'DGPS', 'RTK Float', 'RTK Fixed'] plots_legend = dict( zip(plot_labels, [ref, cur_dgnss, cur_float, cur_fixed])) self.plot.legend.plots = plots_legend self.plot.legend.labels = plot_labels # sets order self.plot.legend.visible = True self.plot.index_axis.tick_label_position = 'inside' self.plot.index_axis.tick_label_color = 'gray' self.plot.index_axis.tick_color = 'gray' self.plot.index_axis.title = 'E (meters)' self.plot.index_axis.title_spacing = 5 self.plot.value_axis.tick_label_position = 'inside' self.plot.value_axis.tick_label_color = 'gray' self.plot.value_axis.tick_color = 'gray' self.plot.value_axis.title = 'N (meters)' self.plot.value_axis.title_spacing = 5 self.plot.padding = (25, 25, 25, 25) self.plot.tools.append(PanTool(self.plot)) zt = ZoomTool(self.plot, zoom_factor=1.1, tool_mode="box", always_on=False) self.plot.overlays.append(zt) self.week = None self.utc_time = None self.age_corrections = None self.heading = None self.nsec = 0 self.link = link self.link.add_callback( self.baseline_callback, [SBP_MSG_BASELINE_NED, SBP_MSG_BASELINE_NED_DEP_A]) self.link.add_callback(self.baseline_heading_callback, [SBP_MSG_BASELINE_HEADING]) self.link.add_callback(self.iar_state_callback, SBP_MSG_IAR_STATE) self.link.add_callback(self.gps_time_callback, [SBP_MSG_GPS_TIME, SBP_MSG_GPS_TIME_DEP_A]) self.link.add_callback(self.utc_time_callback, [SBP_MSG_UTC_TIME]) self.link.add_callback(self.age_corrections_callback, SBP_MSG_AGE_CORRECTIONS) call_repeatedly(0.2, self.solution_draw) self.python_console_cmds = {'baseline': self}
def _tree_time_plot_default(self): plot = Plot(self.plot_data, title="Fractional area covered by trees") plot.plot(["time", "tree_history"]) return plot
def __init__(self, link, plot_history_max=1000): super(BaselineView, self).__init__() self.plot_data = ArrayPlotData(n_fixed=[0.0], e_fixed=[0.0], d_fixed=[0.0], n_float=[0.0], e_float=[0.0], d_float=[0.0], n_satisfied=[0.0], e_satisfied=[0.0], n_unsatisfied=[0.0], e_unsatisfied=[0.0], n_focused=[0.0], e_focused=[0.0], t=[0.0], e_preset=[], n_preset=[]) self.plot_history_max = plot_history_max self.neds = np.empty((plot_history_max, 3)) self.neds[:] = np.NAN self.fixeds = np.zeros(plot_history_max, dtype=bool) self.devs = np.zeros(plot_history_max) self.times = np.zeros(plot_history_max) self.plot = Plot(self.plot_data) color_float = (0.5, 0.5, 1.0) color_fixed = 'orange' color_satisfied = (0.3, 1.0, 0.0) pts_float = self.plot.plot(('e_float', 'n_float'), type='scatter', color=color_float, marker='plus', line_width=2.0, marker_size=8.0) pts_fixed = self.plot.plot(('e_fixed', 'n_fixed'), type='scatter', color=color_fixed, marker='plus', line_width=2.0, marker_size=8.0) threshold_satisfied = self.plot.plot(('e_satisfied', 'n_satisfied'), type='scatter', color=color_satisfied, marker='dot', line_width=0.0, marker_size=4.5) threshold_unsatisfied = self.plot.plot( ('e_unsatisfied', 'n_unsatisfied'), type='scatter', color='red', marker='dot', line_width=0.0, marker_size=4.5) preset = self.plot.plot(('e_preset', 'n_preset'), type='scatter', color='black', marker='plus', marker_size=1.5, line_width=0.0) pts_focused = self.plot.plot(('e_focused', 'n_focused'), type='scatter', color='black', marker='dot', line_width=0.0, marker_size=0.0) #plot_labels = ['RTK Fixed','RTK Float'] #plots_legend = dict(zip(plot_labels, [pts_fixed, pts_float])) #self.plot.legend.plots = plots_legend #self.plot.legend.visible = True self.plot.legend.visible = False self.plot.index_axis.tick_label_position = 'inside' self.plot.index_axis.tick_label_color = 'gray' self.plot.index_axis.tick_color = 'gray' self.plot.index_axis.title = 'E (meters)' self.plot.index_axis.title_spacing = 5 self.plot.value_axis.tick_label_position = 'inside' self.plot.value_axis.tick_label_color = 'gray' self.plot.value_axis.tick_color = 'gray' self.plot.value_axis.title = 'N (meters)' self.plot.value_axis.title_spacing = 5 self.plot.padding = (25, 25, 25, 25) self.plot.tools.append(PanTool(self.plot)) zt = ZoomTool(self.plot, zoom_factor=1.1, tool_mode="box", always_on=False) self.plot.overlays.append(zt) self.week = None self.nsec = 0 self.link = link self.link.add_callback(self._baseline_callback_ned, SBP_MSG_BASELINE_NED) self.cnt = 0 self.dev_list = [] self.data_dict = {} self.presets = self._read_preset_points() self.settings_yaml = SettingsList() self.position_threshold = str( self.settings_yaml.get_threshold_field('position')) self.depth_threshold = str( self.settings_yaml.get_threshold_field('depth')) self.time_threshold = str( self.settings_yaml.get_threshold_field('time')) self.zoom_once = False self.python_console_cmds = {'baseline': self}
def _forest_plot_default(self): plot = Plot(self.plot_data) plot.img_plot("forest_image") plot.bounds = [0., 2.0] return plot
def test_process_2d_bounds_cell_plot(self): # behavior: _process_2d_bounds accepts all possible ways to set x and y # bounds in 2d plots and returns a 1d array with equally spaced # intervals between the lower and upper bound of the data. The number # of elements in the 1d array must be of one element larger than the # shape of the data, because this is cell data. height, width = 20, 10 array_data = np.ones(shape=(height, width)) plot = Plot() # bounds is None : infer from array_data shape xs = plot._process_2d_bounds(None, array_data, 1, cell_plot=True) self.assertEqual(xs.shape[0], width + 1) ys = plot._process_2d_bounds(None, array_data, 0, cell_plot=True) self.assertEqual(ys.shape[0], height + 1) # bounds is a tuple : it defines lower and upper range bounds = (1.0, 100.0) xs = plot._process_2d_bounds(bounds, array_data, 1, cell_plot=True) self.assertEqual(xs.shape[0], width + 1) self.assertEqual(xs[0], bounds[0]) self.assertEqual(xs[-1], bounds[1]) # bounds is a 1D array: the first and last elements are used to create # equally spaced intervals. Bounds must be of one element larger than the # corresponding axis in array_data, or it will raise a Value error bounds = np.zeros((height + 1, )) bounds[0], bounds[-1] = 0.2, 21.3 ys = plot._process_2d_bounds(bounds, array_data, 0, cell_plot=True) self.assertEqual(ys.shape[0], height + 1) self.assertEqual(ys[0], bounds[0]) self.assertEqual(ys[-1], bounds[-1]) with assert_raises(ValueError): bounds = np.zeros((width // 2, )) plot._process_2d_bounds(bounds, array_data, 0, cell_plot=True) # bounds is a 2D array: the first and last elements along the appropriate # axis are used to create equally spaced intervals. # The size of the bounds must be the same as the data array, or this # sill raise a ValueError xbounds, ybounds = np.meshgrid(np.arange(width + 1), np.arange(height + 1)) xs = plot._process_2d_bounds(xbounds, array_data, 1, cell_plot=True) self.assertEqual(xs.shape[0], width + 1) self.assertEqual(xs[0], xbounds[0, 0]) self.assertEqual(xs[-1], xbounds[0, -1]) with assert_raises(ValueError): plot._process_2d_bounds(xbounds[:, :5], array_data, 1, cell_plot=True) ys = plot._process_2d_bounds(ybounds, array_data, 0, cell_plot=True) self.assertEqual(ys.shape[0], height + 1) self.assertEqual(ys[0], ybounds[0, 0]) self.assertEqual(ys[-1], ybounds[-1, 0]) with assert_raises(ValueError): plot._process_2d_bounds(ybounds[:5, :], array_data, 0, cell_plot=True)
class BaselineView(HasTraits): # This mapping should match the flag definitions in libsbp for # the MsgBaselineNED message. While this isn't strictly necessary # it helps avoid confusion python_console_cmds = Dict() last_plot_update_time = Float() last_stale_update_time = Float() table = List() logging_b = Bool(False) directory_name_b = File plot = Instance(Plot) plot_data = Instance(ArrayPlotData) running = Bool(True) zoomall = Bool(False) position_centered = Bool(False) clear_button = SVGButton( label='', tooltip='Clear', filename=resource_filename('console/images/iconic/x.svg'), width=16, height=16) zoomall_button = SVGButton( label='', tooltip='Zoom All', toggle=True, filename=resource_filename('console/images/iconic/fullscreen.svg'), width=16, height=16) center_button = SVGButton( label='', tooltip='Center on Baseline', toggle=True, filename=resource_filename('console/images/iconic/target.svg'), width=16, height=16) paused_button = SVGButton( label='', tooltip='Pause', toggle_tooltip='Run', toggle=True, filename=resource_filename('console/images/iconic/pause.svg'), toggle_filename=resource_filename('console/images/iconic/play.svg'), width=16, height=16) reset_button = Button(label='Reset Filters') traits_view = View( HSplit( Item('table', style='readonly', editor=TabularEditor(adapter=SimpleAdapter()), show_label=False, width=0.3), VGroup( HGroup( Item('paused_button', show_label=False), Item('clear_button', show_label=False), Item('zoomall_button', show_label=False), Item('center_button', show_label=False), Item('reset_button', show_label=False), ), Item( 'plot', show_label=False, editor=ComponentEditor(bgcolor=(0.8, 0.8, 0.8)), )))) def _zoomall_button_fired(self): self.zoomall = not self.zoomall def _center_button_fired(self): self.position_centered = not self.position_centered def _paused_button_fired(self): self.running = not self.running def _reset_button_fired(self): self.link(MsgResetFilters(filter=0)) def _get_update_current(self, current_dict={}): out_dict = { 'cur_n_fixed': [], 'cur_e_fixed': [], 'cur_d_fixed': [], 'cur_n_float': [], 'cur_e_float': [], 'cur_d_float': [], 'cur_n_dgnss': [], 'cur_e_dgnss': [], 'cur_d_dgnss': [] } out_dict.update(current_dict) return out_dict def _synchronize_plot_data_by_mode(self, mode_string, update_current=False): # do all required plot_data updates for a single # new solution with mode defined by mode_string pending_update = { 'n_' + mode_string: [n for n in self.slns['n_' + mode_string] if not np.isnan(n)], 'e_' + mode_string: [e for e in self.slns['e_' + mode_string] if not np.isnan(e)] } if update_current: current = {} if len(pending_update['n_' + mode_string]) != 0: current = { 'cur_n_' + mode_string: [pending_update['n_' + mode_string][-1]], 'cur_e_' + mode_string: [pending_update['e_' + mode_string][-1]] } else: current = { 'cur_n_' + mode_string: [], 'cur_e_' + mode_string: [] } pending_update.update(self._get_update_current(current)) self.plot_data.update_data(pending_update) def _append_empty_sln_data(self, exclude_mode=None): for each_mode in mode_string_dict.values(): if exclude_mode is None or each_mode != exclude_mode: self.slns['n_' + each_mode].append(np.nan) self.slns['e_' + each_mode].append(np.nan) def _update_sln_data_by_mode(self, soln, mode_string): # do backend deque updates for a new solution of type # mode string self.slns['n_' + mode_string].append(soln.n) self.slns['e_' + mode_string].append(soln.e) # Rotate old data out by appending to deque self._append_empty_sln_data(exclude_mode=mode_string) def _clr_sln_data(self): for each in self.slns: self.slns[each].clear() def _reset_remove_current(self): self.plot_data.update_data(self._get_update_current()) def _clear_history(self): self._clr_sln_data() pending_update = { 'n_fixed': [], 'e_fixed': [], 'd_fixed': [], 'n_float': [], 'e_float': [], 'd_float': [], 'n_dgnss': [], 'e_dgnss': [], 'd_dgnss': [] } pending_update.update(self._get_update_current()) self.plot_data.update(pending_update) def _clear_button_fired(self): self._clear_history() def age_corrections_callback(self, sbp_msg, **metadata): age_msg = MsgAgeCorrections(sbp_msg) if age_msg.age != 0xFFFF: self.age_corrections = age_msg.age / 10.0 else: self.age_corrections = None self.last_age_corr_receipt_time = monotonic() def gps_time_callback(self, sbp_msg, **metadata): if sbp_msg.msg_type == SBP_MSG_GPS_TIME_DEP_A: time_msg = MsgGPSTimeDepA(sbp_msg) flags = 1 elif sbp_msg.msg_type == SBP_MSG_GPS_TIME: time_msg = MsgGPSTime(sbp_msg) flags = time_msg.flags if flags != 0: self.week = time_msg.wn self.nsec = time_msg.ns_residual def utc_time_callback(self, sbp_msg, **metadata): tmsg = MsgUtcTime(sbp_msg) microseconds = int(tmsg.ns / 1000.00) if tmsg.flags & 0x1 == 1: dt = datetime.datetime(tmsg.year, tmsg.month, tmsg.day, tmsg.hours, tmsg.minutes, tmsg.seconds, microseconds) self.utc_time = dt self.utc_time_flags = tmsg.flags if (tmsg.flags >> 3) & 0x3 == 0: self.utc_source = "Factory Default" elif (tmsg.flags >> 3) & 0x3 == 1: self.utc_source = "Non Volatile Memory" elif (tmsg.flags >> 3) & 0x3 == 2: self.utc_source = "Decoded this Session" else: self.utc_source = "Unknown" else: self.utc_time = None self.utc_source = None def baseline_heading_callback(self, sbp_msg, **metadata): headingMsg = MsgBaselineHeading(sbp_msg) if headingMsg.flags & 0x7 != 0: self.heading = headingMsg.heading * 1e-3 else: self.heading = "---" def baseline_callback(self, sbp_msg, **metadata): soln = MsgBaselineNEDDepA(sbp_msg) table = [] soln.n = soln.n * 1e-3 soln.e = soln.e * 1e-3 soln.d = soln.d * 1e-3 soln.h_accuracy = soln.h_accuracy * 1e-3 soln.v_accuracy = soln.v_accuracy * 1e-3 dist = np.sqrt(soln.n**2 + soln.e**2 + soln.d**2) tow = soln.tow * 1e-3 if self.nsec is not None: tow += self.nsec * 1e-9 ((tloc, secloc), (tgps, secgps)) = log_time_strings(self.week, tow) if self.utc_time is not None: ((tutc, secutc)) = datetime_2_str(self.utc_time) if self.directory_name_b == '': filepath = time.strftime("baseline_log_%Y%m%d-%H%M%S.csv") else: filepath = os.path.join( self.directory_name_b, time.strftime("baseline_log_%Y%m%d-%H%M%S.csv")) if not self.logging_b: self.log_file = None if self.logging_b: if self.log_file is None: self.log_file = sopen(filepath, 'w') self.log_file.write( 'pc_time,gps_time,tow(sec),north(meters),east(meters),down(meters),h_accuracy(meters),v_accuracy(meters),' 'distance(meters),num_sats,flags,num_hypothesis\n') log_str_gps = '' if tgps != '' and secgps != 0: log_str_gps = "{0}:{1:06.6f}".format(tgps, float(secgps)) self.log_file.write( '%s,%s,%.3f,%.4f,%.4f,%.4f,%.4f,%.4f,%.4f,%d,%d,%d\n' % ("{0}:{1:06.6f}".format(tloc, float(secloc)), log_str_gps, tow, soln.n, soln.e, soln.d, soln.h_accuracy, soln.v_accuracy, dist, soln.n_sats, soln.flags, self.num_hyps)) self.log_file.flush() self.last_mode = get_mode(soln) if self.last_mode < 1: table.append(('GPS Week', EMPTY_STR)) table.append(('GPS TOW', EMPTY_STR)) table.append(('GPS Time', EMPTY_STR)) table.append(('UTC Time', EMPTY_STR)) table.append(('UTC Src', EMPTY_STR)) table.append(('N', EMPTY_STR)) table.append(('E', EMPTY_STR)) table.append(('D', EMPTY_STR)) table.append(('Horiz Acc', EMPTY_STR)) table.append(('Vert Acc', EMPTY_STR)) table.append(('Dist.', EMPTY_STR)) table.append(('Sats Used', EMPTY_STR)) table.append(('Flags', EMPTY_STR)) table.append(('Mode', EMPTY_STR)) table.append(('Heading', EMPTY_STR)) table.append(('Corr. Age [s]', EMPTY_STR)) else: self.last_btime_update = monotonic() if self.week is not None: table.append(('GPS Week', str(self.week))) table.append(('GPS TOW', "{:.3f}".format(tow))) if self.week is not None: table.append( ('GPS Time', "{0}:{1:06.3f}".format(tgps, float(secgps)))) if self.utc_time is not None: table.append( ('UTC Time', "{0}:{1:06.3f}".format(tutc, float(secutc)))) table.append(('UTC Src', self.utc_source)) table.append(('N', "{:.12g}".format(soln.n))) table.append(('E', "{:.12g}".format(soln.e))) table.append(('D', "{:.12g}".format(soln.d))) table.append(('Horiz Acc', "{:.12g}".format(soln.h_accuracy))) table.append(('Vert Acc', "{:.12g}".format(soln.v_accuracy))) table.append(('Dist.', "{0:.3f}".format(dist))) table.append(('Sats Used', soln.n_sats)) table.append(('Flags', '0x%02x' % soln.flags)) table.append(('Mode', mode_dict[self.last_mode])) if self.heading is not None: table.append(('Heading', self.heading)) if self.age_corrections is not None: table.append(('Corr. Age [s]', self.age_corrections)) else: table.append(('Corr. Age [s]', EMPTY_STR)) self.table = table if self.last_mode != 0: self.last_soln = soln mode_string = mode_string_dict[self.last_mode] if mode_string not in self.pending_draw_modes: # if we don't already have a pending upate for that mode self.pending_draw_modes.append(mode_string) self.list_lock.acquire() self._update_sln_data_by_mode(soln, mode_string) self.list_lock.release() else: self.list_lock.acquire() self._append_empty_sln_data(soln) self.list_lock.release() if monotonic() - self.last_plot_update_time > GUI_UPDATE_PERIOD: self.update_scheduler.schedule_update('_solution_draw', self._solution_draw) def _solution_draw(self): self.list_lock.acquire() current_time = monotonic() self.last_plot_update_time = current_time pending_draw_modes = self.pending_draw_modes current_mode = pending_draw_modes[-1] if len( pending_draw_modes) > 0 else None # Periodically, we make sure to redraw older data to expire old plot data if current_time - self.last_stale_update_time > STALE_DATA_PERIOD: # we don't update old solution modes every timestep to try and save CPU pending_draw_modes = list(mode_string_dict.values()) self.last_stale_update_time = current_time for mode_string in pending_draw_modes: if self.running: update_current = mode_string == current_mode if current_mode else True self._synchronize_plot_data_by_mode(mode_string, update_current) if mode_string in self.pending_draw_modes: self.pending_draw_modes.remove(mode_string) self.list_lock.release() # make the zoomall win over the position centered button if not self.zoomall and self.position_centered and self.running and self.last_soln: d = (self.plot.index_range.high - self.plot.index_range.low) / 2. self.plot.index_range.set_bounds(self.last_soln.e - d, self.last_soln.e + d) d = (self.plot.value_range.high - self.plot.value_range.low) / 2. self.plot.value_range.set_bounds(self.last_soln.n - d, self.last_soln.n + d) if self.zoomall: plot_square_axes(self.plot, ('e_fixed', 'e_float', 'e_dgnss'), ('n_fixed', 'n_float', 'n_dgnss')) def __init__(self, link, plot_history_max=1000, dirname=''): super(BaselineView, self).__init__() self.pending_draw_modes = [] self.log_file = None self.directory_name_b = dirname self.num_hyps = 0 self.last_hyp_update = 0 self.last_btime_update = 0 self.last_age_corections_receipt_time = 0 self.last_soln = None self.last_mode = 0 self.last_plot_update_time = 0 self.last_stale_update_time = 0 self.slns = { 'n_fixed': deque(maxlen=PLOT_HISTORY_MAX), 'e_fixed': deque(maxlen=PLOT_HISTORY_MAX), 'd_fixed': deque(maxlen=PLOT_HISTORY_MAX), 'n_float': deque(maxlen=PLOT_HISTORY_MAX), 'e_float': deque(maxlen=PLOT_HISTORY_MAX), 'd_float': deque(maxlen=PLOT_HISTORY_MAX), 'n_dgnss': deque(maxlen=PLOT_HISTORY_MAX), 'e_dgnss': deque(maxlen=PLOT_HISTORY_MAX), 'd_dgnss': deque(maxlen=PLOT_HISTORY_MAX) } self.plot_data = ArrayPlotData(n_fixed=[], e_fixed=[], n_float=[], e_float=[], n_dgnss=[], e_dgnss=[], t=[0.0], ref_n=[0.0], ref_e=[0.0], cur_e_fixed=[], cur_n_fixed=[], cur_e_float=[], cur_n_float=[], cur_e_dgnss=[], cur_n_dgnss=[]) self.list_lock = threading.Lock() self.plot = Plot(self.plot_data) self.plot.plot(('e_float', 'n_float'), type='scatter', color=color_dict[FLOAT_MODE], marker='dot', line_width=0.0, marker_size=1.0) self.plot.plot(('e_fixed', 'n_fixed'), type='scatter', color=color_dict[FIXED_MODE], marker='dot', line_width=0.0, marker_size=1.0) self.plot.plot(('e_dgnss', 'n_dgnss'), type='scatter', color=color_dict[DGNSS_MODE], marker='dot', line_width=0.0, marker_size=1.0) ref = self.plot.plot(('ref_e', 'ref_n'), type='scatter', color='red', marker='plus', marker_size=5, line_width=1.5) cur_fixed = self.plot.plot(('cur_e_fixed', 'cur_n_fixed'), type='scatter', color=color_dict[FIXED_MODE], marker='plus', marker_size=5, line_width=1.5) cur_float = self.plot.plot(('cur_e_float', 'cur_n_float'), type='scatter', color=color_dict[FLOAT_MODE], marker='plus', marker_size=5, line_width=1.5) cur_dgnss = self.plot.plot(('cur_e_dgnss', 'cur_n_dgnss'), type='scatter', color=color_dict[DGNSS_MODE], marker='plus', line_width=1.5, marker_size=5) plot_labels = [' Base Position', 'DGPS', 'RTK Float', 'RTK Fixed'] plots_legend = dict( zip(plot_labels, [ref, cur_dgnss, cur_float, cur_fixed])) self.plot.legend.plots = plots_legend self.plot.legend.labels = plot_labels # sets order self.plot.legend.visible = True self.plot.index_axis.tick_label_position = 'inside' self.plot.index_axis.tick_label_color = 'gray' self.plot.index_axis.tick_color = 'gray' self.plot.index_axis.title = 'E (meters)' self.plot.index_axis.title_spacing = 5 self.plot.value_axis.tick_label_position = 'inside' self.plot.value_axis.tick_label_color = 'gray' self.plot.value_axis.tick_color = 'gray' self.plot.value_axis.title = 'N (meters)' self.plot.value_axis.title_spacing = 5 self.plot.padding = (25, 25, 25, 25) self.plot.tools.append(PanTool(self.plot)) zt = ZoomTool(self.plot, zoom_factor=1.1, tool_mode="box", always_on=False) self.plot.overlays.append(zt) self.week = None self.utc_time = None self.age_corrections = None self.heading = "---" self.nsec = 0 self.link = link self.link.add_callback( self.baseline_callback, [SBP_MSG_BASELINE_NED, SBP_MSG_BASELINE_NED_DEP_A]) self.link.add_callback(self.baseline_heading_callback, [SBP_MSG_BASELINE_HEADING]) self.link.add_callback(self.gps_time_callback, [SBP_MSG_GPS_TIME, SBP_MSG_GPS_TIME_DEP_A]) self.link.add_callback(self.utc_time_callback, [SBP_MSG_UTC_TIME]) self.link.add_callback(self.age_corrections_callback, SBP_MSG_AGE_CORRECTIONS) self.python_console_cmds = {'baseline': self} self.update_scheduler = UpdateScheduler()
def _histograms_default(self): plot = Plot(self.plot_data) plot.plot(["fractions", "density_function"], color="green") return plot
class plot_window(HasTraits): _plot_data = Instance(ArrayPlotData) _plot = Instance(Plot) _click_tool = Instance(clicker_tool) _img_plot = Instance(ImagePlot) _right_click_avail = 0 name = Str view = View(Item(name='_plot', editor=ComponentEditor(), show_label=False), ) def __init__(self): # -------------- Initialization of plot system ---------------- padd = 25 self._plot_data = ArrayPlotData() self._x = [] self._y = [] self.man_ori = [1, 2, 3, 4] self._plot = Plot(self._plot_data, default_origin="top left") self._plot.padding_left = padd self._plot.padding_right = padd self._plot.padding_top = padd self._plot.padding_bottom = padd self._quiverplots = [] # ------------------------------------------------------------- def left_clicked_event(self): print("left clicked") if len(self._x) < 4: self._x.append(self._click_tool.x) self._y.append(self._click_tool.y) print self._x print self._y self.drawcross("coord_x", "coord_y", self._x, self._y, "red", 5) self._plot.overlays = [] self.plot_num_overlay(self._x, self._y, self.man_ori) def right_clicked_event(self): print("right clicked") if len(self._x) > 0: self._x.pop() self._y.pop() print self._x print self._y self.drawcross("coord_x", "coord_y", self._x, self._y, "red", 5) self._plot.overlays = [] self.plot_num_overlay(self._x, self._y, self.man_ori) else: if (self._right_click_avail): print "deleting point" self.py_rclick_delete(self._click_tool.x, self._click_tool.y, self.cameraN) x = [] y = [] self.py_get_pix_N(x, y, self.cameraN) self.drawcross("x", "y", x[0], y[0], "blue", 4) def attach_tools(self): self._click_tool = clicker_tool(self._img_plot) self._click_tool.on_trait_change(self.left_clicked_event, 'left_changed') self._click_tool.on_trait_change(self.right_clicked_event, 'right_changed') self._img_plot.tools.append(self._click_tool) self._zoom_tool = SimpleZoom(component=self._plot, tool_mode="box", always_on=False) self._zoom_tool.max_zoom_out_factor = 1.0 self._img_plot.tools.append(self._zoom_tool) if self._plot.index_mapper is not None: self._plot.index_mapper.on_trait_change(self.handle_mapper, 'updated', remove=False) if self._plot.value_mapper is not None: self._plot.value_mapper.on_trait_change(self.handle_mapper, 'updated', remove=False) def drawcross(self, str_x, str_y, x, y, color1, mrk_size): self._plot_data.set_data(str_x, x) self._plot_data.set_data(str_y, y) self._plot.plot((str_x, str_y), type="scatter", color=color1, marker="plus", marker_size=mrk_size) self._plot.request_redraw() def drawline(self, str_x, str_y, x1, y1, x2, y2, color1): self._plot_data.set_data(str_x, [x1, x2]) self._plot_data.set_data(str_y, [y1, y2]) self._plot.plot((str_x, str_y), type="line", color=color1) self._plot.request_redraw() def drawquiver(self, x1c, y1c, x2c, y2c, color, linewidth=1.0, scale=1.0): """ drawquiver draws multiple lines at once on the screen x1,y1->x2,y2 in the current camera window parameters: x1c - array of x1 coordinates y1c - array of y1 coordinates x2c - array of x2 coordinates y2c - array of y2 coordinates color - color of the line linewidth - linewidth of the line example usage: drawquiver ([100,200],[100,100],[400,400],[300,200],'red',linewidth=2.0) draws 2 red lines with thickness = 2 : 100,100->400,300 and 200,100->400,200 """ x1, y1, x2, y2 = self.remove_short_lines(x1c, y1c, x2c, y2c, min_length=0) if len(x1) > 0: xs = ArrayDataSource(x1) ys = ArrayDataSource(y1) quiverplot = QuiverPlot( index=xs, value=ys, index_mapper=LinearMapper(range=self._plot.index_mapper.range), value_mapper=LinearMapper(range=self._plot.value_mapper.range), origin=self._plot.origin, arrow_size=0, line_color=color, line_width=linewidth, ep_index=np.array(x2) * scale, ep_value=np.array(y2) * scale) self._plot.add(quiverplot) # we need this to track how many quiverplots are in the current # plot self._quiverplots.append(quiverplot) # import pdb; pdb.set_trace() def remove_short_lines(self, x1, y1, x2, y2, min_length=2): """ removes short lines from the array of lines parameters: x1,y1,x2,y2 - start and end coordinates of the lines returns: x1f,y1f,x2f,y2f - start and end coordinates of the lines, with short lines removed example usage: x1,y1,x2,y2=remove_short_lines([100,200,300],[100,200,300],[100,200,300],[102,210,320]) 3 input lines, 1 short line will be removed (100,100->100,102) returned coordinates: x1=[200,300]; y1=[200,300]; x2=[200,300]; y2=[210,320] """ # dx, dy = 2, 2 # minimum allowable dx,dy x1f, y1f, x2f, y2f = [], [], [], [] for i in range(len(x1)): if abs(x1[i] - x2[i]) > min_length or abs(y1[i] - y2[i]) > min_length: x1f.append(x1[i]) y1f.append(y1[i]) x2f.append(x2[i]) y2f.append(y2[i]) return x1f, y1f, x2f, y2f def handle_mapper(self): for i in range(0, len(self._plot.overlays)): if hasattr(self._plot.overlays[i], 'real_position'): coord_x1, coord_y1 = self._plot.map_screen( [self._plot.overlays[i].real_position])[0] self._plot.overlays[i].alternate_position = (coord_x1, coord_y1) def plot_num_overlay(self, x, y, txt): for i in range(0, len(x)): coord_x, coord_y = self._plot.map_screen([(x[i], y[i])])[0] ovlay = TextBoxOverlay(component=self._plot, text=str(txt[i]), alternate_position=(coord_x, coord_y), real_position=(x[i], y[i]), text_color="white", border_color="red") self._plot.overlays.append(ovlay) def update_image(self, image, is_float): if is_float: self._plot_data.set_data('imagedata', image.astype(np.float)) else: self._plot_data.set_data('imagedata', image.astype(np.byte)) self._plot.request_redraw()
def _fire_time_plot_default(self): plot = Plot(self.plot_data, title="Fractional area with fires") plot.plot(["time", "fire_history"]) return plot
def __init__(self, link, dirname=''): super(SolutionView, self).__init__() self.lats = np.zeros(self.plot_history_max) self.lngs = np.zeros(self.plot_history_max) self.alts = np.zeros(self.plot_history_max) self.tows = np.zeros(self.plot_history_max) self.modes = np.zeros(self.plot_history_max) self.log_file = None self.directory_name_v = dirname self.directory_name_p = dirname self.vel_log_file = None self.last_stime_update = 0 self.last_soln = None self.counter = 0 self.latitude_list = [] self.longitude_list = [] self.altitude_list = [] self.altitude = 0 self.longitude = 0 self.latitude = 0 self.last_pos_mode = 0 self.plot_data = ArrayPlotData(lat_spp=[], lng_spp=[], alt_spp=[], cur_lat_spp=[], cur_lng_spp=[], lat_dgnss=[], lng_dgnss=[], alt_dgnss=[], cur_lat_dgnss=[], cur_lng_dgnss=[], lat_float=[], lng_float=[], alt_float=[], cur_lat_float=[], cur_lng_float=[], lat_fixed=[], lng_fixed=[], alt_fixed=[], cur_lat_fixed=[], cur_lng_fixed=[]) self.plot = Plot(self.plot_data) # 1000 point buffer self.plot.plot(('lng_spp', 'lat_spp'), type='line', line_width=0.1, name='', color=color_dict[SPP_MODE]) self.plot.plot(('lng_spp', 'lat_spp'), type='scatter', name='', color=color_dict[SPP_MODE], marker='dot', line_width=0.0, marker_size=1.0) self.plot.plot(('lng_dgnss', 'lat_dgnss'), type='line', line_width=0.1, name='', color=color_dict[DGNSS_MODE]) self.plot.plot(('lng_dgnss', 'lat_dgnss'), type='scatter', name='', color=color_dict[DGNSS_MODE], marker='dot', line_width=0.0, marker_size=1.0) self.plot.plot(('lng_float', 'lat_float'), type='line', line_width=0.1, name='', color=color_dict[FLOAT_MODE]) self.plot.plot(('lng_float', 'lat_float'), type='scatter', name='', color=color_dict[FLOAT_MODE], marker='dot', line_width=0.0, marker_size=1.0) self.plot.plot(('lng_fixed', 'lat_fixed'), type='line', line_width=0.1, name='', color=color_dict[FIXED_MODE]) self.plot.plot(('lng_fixed', 'lat_fixed'), type='scatter', name='', color=color_dict[FIXED_MODE], marker='dot', line_width=0.0, marker_size=1.0) # current values spp = self.plot.plot(('cur_lng_spp', 'cur_lat_spp'), type='scatter', name=mode_dict[SPP_MODE], color=color_dict[SPP_MODE], marker='plus', line_width=1.5, marker_size=5.0) dgnss = self.plot.plot(('cur_lng_dgnss', 'cur_lat_dgnss'), type='scatter', name=mode_dict[DGNSS_MODE], color=color_dict[DGNSS_MODE], marker='plus', line_width=1.5, marker_size=5.0) rtkfloat = self.plot.plot(('cur_lng_float', 'cur_lat_float'), type='scatter', name=mode_dict[FLOAT_MODE], color=color_dict[FLOAT_MODE], marker='plus', line_width=1.5, marker_size=5.0) rtkfix = self.plot.plot(('cur_lng_fixed', 'cur_lat_fixed'), type='scatter', name=mode_dict[FIXED_MODE], color=color_dict[FIXED_MODE], marker='plus', line_width=1.5, marker_size=5.0) plot_labels = ['SPP', 'DGPS', "RTK float", "RTK fixed"] plots_legend = dict(zip(plot_labels, [spp, dgnss, rtkfloat, rtkfix])) self.plot.legend.plots = plots_legend self.plot.legend.labels = plot_labels # sets order self.plot.legend.visible = True self.plot.index_axis.tick_label_position = 'inside' self.plot.index_axis.tick_label_color = 'gray' self.plot.index_axis.tick_color = 'gray' self.plot.index_axis.title = 'Longitude (degrees)' self.plot.index_axis.title_spacing = 5 self.plot.value_axis.tick_label_position = 'inside' self.plot.value_axis.tick_label_color = 'gray' self.plot.value_axis.tick_color = 'gray' self.plot.value_axis.title = 'Latitude (degrees)' self.plot.value_axis.title_spacing = 5 self.plot.padding = (25, 25, 25, 25) self.plot.tools.append(PanTool(self.plot)) zt = ZoomTool(self.plot, zoom_factor=1.1, tool_mode="box", always_on=False) self.plot.overlays.append(zt) self.link = link self.link.add_callback(self._pos_llh_callback, [SBP_MSG_POS_LLH_DEP_A, SBP_MSG_POS_LLH]) self.link.add_callback(self.vel_ned_callback, [SBP_MSG_VEL_NED_DEP_A, SBP_MSG_VEL_NED]) self.link.add_callback(self.dops_callback, [SBP_MSG_DOPS_DEP_A, SBP_MSG_DOPS]) self.link.add_callback(self.gps_time_callback, [SBP_MSG_GPS_TIME_DEP_A, SBP_MSG_GPS_TIME]) self.link.add_callback(self.utc_time_callback, [SBP_MSG_UTC_TIME]) self.link.add_callback(self.age_corrections_callback, SBP_MSG_AGE_CORRECTIONS) self.week = None self.utc_time = None self.age_corrections = None self.nsec = 0 self.python_console_cmds = { 'solution': self, }
def __init__(self, link, plot_history_max=1000, dirname=''): super(BaselineView, self).__init__() self.pending_draw_modes = [] self.log_file = None self.directory_name_b = dirname self.num_hyps = 0 self.last_hyp_update = 0 self.last_btime_update = 0 self.last_age_corections_receipt_time = 0 self.last_soln = None self.last_mode = 0 self.last_plot_update_time = 0 self.last_stale_update_time = 0 self.slns = { 'n_fixed': deque(maxlen=PLOT_HISTORY_MAX), 'e_fixed': deque(maxlen=PLOT_HISTORY_MAX), 'd_fixed': deque(maxlen=PLOT_HISTORY_MAX), 'n_float': deque(maxlen=PLOT_HISTORY_MAX), 'e_float': deque(maxlen=PLOT_HISTORY_MAX), 'd_float': deque(maxlen=PLOT_HISTORY_MAX), 'n_dgnss': deque(maxlen=PLOT_HISTORY_MAX), 'e_dgnss': deque(maxlen=PLOT_HISTORY_MAX), 'd_dgnss': deque(maxlen=PLOT_HISTORY_MAX) } self.plot_data = ArrayPlotData(n_fixed=[], e_fixed=[], n_float=[], e_float=[], n_dgnss=[], e_dgnss=[], t=[0.0], ref_n=[0.0], ref_e=[0.0], cur_e_fixed=[], cur_n_fixed=[], cur_e_float=[], cur_n_float=[], cur_e_dgnss=[], cur_n_dgnss=[]) self.list_lock = threading.Lock() self.plot = Plot(self.plot_data) self.plot.plot(('e_float', 'n_float'), type='scatter', color=color_dict[FLOAT_MODE], marker='dot', line_width=0.0, marker_size=1.0) self.plot.plot(('e_fixed', 'n_fixed'), type='scatter', color=color_dict[FIXED_MODE], marker='dot', line_width=0.0, marker_size=1.0) self.plot.plot(('e_dgnss', 'n_dgnss'), type='scatter', color=color_dict[DGNSS_MODE], marker='dot', line_width=0.0, marker_size=1.0) ref = self.plot.plot(('ref_e', 'ref_n'), type='scatter', color='red', marker='plus', marker_size=5, line_width=1.5) cur_fixed = self.plot.plot(('cur_e_fixed', 'cur_n_fixed'), type='scatter', color=color_dict[FIXED_MODE], marker='plus', marker_size=5, line_width=1.5) cur_float = self.plot.plot(('cur_e_float', 'cur_n_float'), type='scatter', color=color_dict[FLOAT_MODE], marker='plus', marker_size=5, line_width=1.5) cur_dgnss = self.plot.plot(('cur_e_dgnss', 'cur_n_dgnss'), type='scatter', color=color_dict[DGNSS_MODE], marker='plus', line_width=1.5, marker_size=5) plot_labels = [' Base Position', 'DGPS', 'RTK Float', 'RTK Fixed'] plots_legend = dict( zip(plot_labels, [ref, cur_dgnss, cur_float, cur_fixed])) self.plot.legend.plots = plots_legend self.plot.legend.labels = plot_labels # sets order self.plot.legend.visible = True self.plot.index_axis.tick_label_position = 'inside' self.plot.index_axis.tick_label_color = 'gray' self.plot.index_axis.tick_color = 'gray' self.plot.index_axis.title = 'E (meters)' self.plot.index_axis.title_spacing = 5 self.plot.value_axis.tick_label_position = 'inside' self.plot.value_axis.tick_label_color = 'gray' self.plot.value_axis.tick_color = 'gray' self.plot.value_axis.title = 'N (meters)' self.plot.value_axis.title_spacing = 5 self.plot.padding = (25, 25, 25, 25) self.plot.tools.append(PanTool(self.plot)) zt = ZoomTool(self.plot, zoom_factor=1.1, tool_mode="box", always_on=False) self.plot.overlays.append(zt) self.week = None self.utc_time = None self.age_corrections = None self.heading = "---" self.nsec = 0 self.link = link self.link.add_callback( self.baseline_callback, [SBP_MSG_BASELINE_NED, SBP_MSG_BASELINE_NED_DEP_A]) self.link.add_callback(self.baseline_heading_callback, [SBP_MSG_BASELINE_HEADING]) self.link.add_callback(self.gps_time_callback, [SBP_MSG_GPS_TIME, SBP_MSG_GPS_TIME_DEP_A]) self.link.add_callback(self.utc_time_callback, [SBP_MSG_UTC_TIME]) self.link.add_callback(self.age_corrections_callback, SBP_MSG_AGE_CORRECTIONS) self.python_console_cmds = {'baseline': self} self.update_scheduler = UpdateScheduler()
def __init__(self, link): super(IMUView, self).__init__() self.acc = np.empty((NUM_POINTS, 3)) self.gyro = np.empty((NUM_POINTS, 3)) self.plot_data = ArrayPlotData(t=np.arange(NUM_POINTS), acc_x=[0.0], acc_y=[0.0], acc_z=[0.0], gyr_x=[0.0], gyr_y=[0.0], gyr_z=[0.0]) self.plot = Plot(self.plot_data, auto_colors=colours_list, emphasized=True) self.plot.title = 'Raw IMU Data' self.plot.title_color = [0, 0, 0.43] self.ylim = self.plot.value_mapper.range self.ylim.low = -32768 self.ylim.high = 32767 #self.plot.value_range.bounds_func = lambda l, h, m, tb: (0, h * (1 + m)) self.plot.value_axis.orientation = 'right' self.plot.value_axis.axis_line_visible = False self.plot.value_axis.title = 'LSB count' self.legend_visible = True self.plot.legend.visible = True self.plot.legend.align = 'll' self.plot.legend.line_spacing = 1 self.plot.legend.font = 'modern 8' self.plot.legend.draw_layer = 'overlay' self.plot.legend.tools.append( LegendTool(self.plot.legend, drag_button="right")) acc_x = self.plot.plot(('t', 'acc_x'), type='line', color='auto', name='Accn. X') acc_x = self.plot.plot(('t', 'acc_y'), type='line', color='auto', name='Accn. Y') acc_x = self.plot.plot(('t', 'acc_z'), type='line', color='auto', name='Accn. Z') acc_x = self.plot.plot(('t', 'gyr_x'), type='line', color='auto', name='Gyro X') acc_x = self.plot.plot(('t', 'gyr_y'), type='line', color='auto', name='Gyro Y') acc_x = self.plot.plot(('t', 'gyr_z'), type='line', color='auto', name='Gyro Z') self.link = link self.link.add_callback(self.imu_raw_callback, SBP_MSG_IMU_RAW) self.link.add_callback(self.imu_aux_callback, SBP_MSG_IMU_AUX) self.python_console_cmds = {'track': self}
class ImagePlot(Atom): # container for all plots container = Typed(HPlotContainer) # Plot components within this container: color_plot = Typed(CMapImagePlot) vertical_cross_plot = Typed(Plot) horizontal_cross_plot = Typed(Plot) colorbar = Typed(ColorBar) # plot data pd_all = Typed(ArrayPlotData) #pd_horiz=Instance(ArrayPlotData) #pd_vert=Instance(ArrayPlotData) #private data storage _imag_index = Typed(GridDataSource) _image_value = Typed(ImageData) def __init__(self, x, y, z): super(ImagePlot, self).__init__() self.pd_all = ArrayPlotData(imagedata=z) #self.pd_horiz = ArrayPlotData(x=x, horiz=z[4, :]) #self.pd_vert = ArrayPlotData(y=y, vert=z[:,5]) self._imag_index = GridDataSource(xdata=x, ydata=y, sort_order=("ascending", "ascending")) index_mapper = GridMapper(range=DataRange2D(self._imag_index)) self._imag_index.on_trait_change(self._metadata_changed, "metadata_changed") self._image_value = ImageData(data=z, value_depth=1) color_mapper = jet(DataRange1D(self._image_value)) self.color_plot = CMapImagePlot(index=self._imag_index, index_mapper=index_mapper, value=self._image_value, value_mapper=color_mapper, padding=20, use_backbuffer=True, unified_draw=True) #Add axes to image plot left = PlotAxis(orientation='left', title="Frequency (GHz)", mapper=self.color_plot.index_mapper._ymapper, component=self.color_plot) self.color_plot.overlays.append(left) bottom = PlotAxis(orientation='bottom', title="Time (us)", mapper=self.color_plot.index_mapper._xmapper, component=self.color_plot) self.color_plot.overlays.append(bottom) self.color_plot.tools.append( PanTool(self.color_plot, constrain_key="shift")) self.color_plot.overlays.append( ZoomTool(component=self.color_plot, tool_mode="box", always_on=False)) #Add line inspector tool for horizontal and vertical self.color_plot.overlays.append( LineInspector(component=self.color_plot, axis='index_x', inspect_mode="indexed", write_metadata=True, is_listener=True, color="white")) self.color_plot.overlays.append( LineInspector(component=self.color_plot, axis='index_y', inspect_mode="indexed", write_metadata=True, color="white", is_listener=True)) myrange = DataRange1D(low=amin(z), high=amax(z)) cmap = jet self.colormap = cmap(myrange) # Create a colorbar cbar_index_mapper = LinearMapper(range=myrange) self.colorbar = ColorBar(index_mapper=cbar_index_mapper, plot=self.color_plot, padding_top=self.color_plot.padding_top, padding_bottom=self.color_plot.padding_bottom, padding_right=40, resizable='v', width=30) #, ytitle="Magvec (mV)") #create horizontal line plot self.horiz_cross_plot = Plot(self.pd_horiz, resizable="h") self.horiz_cross_plot.height = 100 self.horiz_cross_plot.padding = 20 self.horiz_cross_plot.plot(("x", "horiz")) #, #line_style="dot") # self.cross_plot.plot(("scatter_index","scatter_value","scatter_color"), # type="cmap_scatter", # name="dot", # color_mapper=self._cmap(image_value_range), # marker="circle", # marker_size=8) self.horiz_cross_plot.index_range = self.color_plot.index_range.x_range #create vertical line plot self.vert_cross_plot = Plot(self.pd_vert, width=140, orientation="v", resizable="v", padding=20, padding_bottom=160) self.vert_cross_plot.plot(("y", "vert")) #, # line_style="dot") # self.vert_cross_plot.xtitle="Magvec (mV)" # self.vertica_cross_plot.plot(("vertical_scatter_index", # "vertical_scatter_value", # "vertical_scatter_color"), # type="cmap_scatter", # name="dot", # color_mapper=self._cmap(image_value_range), # marker="circle", # marker_size=8) self.vert_cross_plot.index_range = self.color_plot.index_range.y_range # Create a container and add components self.container = HPlotContainer(padding=40, fill_padding=True, bgcolor="white", use_backbuffer=False) inner_cont = VPlotContainer(padding=0, use_backbuffer=True) inner_cont.add(self.horiz_cross_plot) inner_cont.add(self.color_plot) self.container.add(self.colorbar) self.container.add(inner_cont) self.container.add(self.vert_cross_plot) def _metadata_changed(self, old, new): """ This function takes out a cross section from the image data, based on the line inspector selections, and updates the line and scatter plots.""" #self.cross_plot.value_range.low = self.minz #self.cross_plot.value_range.high = self.maxz #self.cross_plot2.value_range.low = self.minz #self.cross_plot2.value_range.high = self.maxz if self._imag_index.metadata.has_key("selections"): x_ndx, y_ndx = self._imag_index.metadata["selections"] if y_ndx and x_ndx: # xdata, ydata = self._image_index.get_data() # xdata, ydata = xdata.get_data(), ydata.get_data() self.pd_horiz.set_data("horiz", self._image_value.data[y_ndx, :]) self.pd_vert.set_data("vert", self._image_value.data[:, x_ndx]) # scatter_index=array([xdata[x_ndx]]), # scatter_index2=array([ydata[y_ndx]]), # scatter_value=array([self._image_value.data[y_ndx, x_ndx]]), # scatter_value2=array([self._image_value.data[y_ndx, x_ndx]]), # scatter_color=array([self._image_value.data[y_ndx, x_ndx]]), # scatter_color2=array([self._image_value.data[y_ndx, x_ndx]]) # ) # else: # self.pd.update_data({"scatter_value": array([]), # "scatter_value2": array([]), "line_value": array([]), # "line_value2": array([])}) #if __name__ == "__main__": # filename="/Users/thomasaref/Dropbox/Dad stuff/sample3/digitizer/lt/sample3_digitizer_f_sweep_t_300mk_100nspulse.hdf5" # # with h5py.File(filename, 'r') as f: # # time=f["Traces"]["d - AvgTrace - t"][:] # Magvec=f["Traces"]["d - AvgTrace - Magvec"][:] # frequency=f["Data"]["Data"][:] # # for name in f["Data"]: # # print name # # time=squeeze(time) # Magvec=squeeze(Magvec) # frequency=squeeze(frequency) # # x = time[:,0]*1.0e6 # y = frequency[0,:]/1.0e9 # z=transpose(Magvec*1000.0) # # ip=ImagePlot(xs,ys,z) # ip.configure_traits() #class Image_Plot(Atom): # plot_control=Instance(Plot_Control) # xtitle=DelegatesTo('plot_control') # ytitle=DelegatesTo('plot_control') # ztitle=DelegatesTo('plot_control') # request_redraw=DelegatesTo('plot_control') # #ykeys=DelegatesTo('plot_control') # container = Typed(HPlotContainer) # color_plot = Typed(CMapImagePlot) # plot=Instance(Plot) # vertical_cross_plot = Typed(Plot) # horizontal_cross_plot = Typed(Plot) # colorbar = Typed(ColorBar) # pd_all = Instance(ArrayPlotData) # _image_index=Instance(GridDataSource) # _image_value=Instance(ImageData) # data=Dict() # # pd=Instance(ArrayPlotData) # # traits_view = View(Group(Item('container', editor=ComponentEditor(), show_label=False), # orientation='horizontal'), # width=1000, height=700, resizable=True, title="Chaco Plot") # # def _xtitle_changed(self): # self.horiz_cross_plot.x_axis.title=self.xtitle # self.plot.x_axis.title=self.xtitle # # def _ytitle_changed(self): # self.vert_cross_plot.y_axis.title=self.ytitle # self.plot.y_axis.title=self.ytitle # # def _request_redraw_fired(self): # self.color_plot.request_redraw() # self.horiz_cross_plot.request_redraw() # self.vert_cross_plot.request_redraw() # # def __init__(self, data, plot_control): # super(Image_Plot, self).__init__() # self.plot_control=plot_control # z=zeros((len(data['y']['0']), len(data['x']['0']))) # z[:] = nan # for key, item in data['z'].iteritems(): # z[int(key)]=item # x=data['x']['0'] # y=data['y']['0'] # self.pd = ArrayPlotData(z=z, x=x, y=y, horiz=z[0, :], vert=z[:, 0]) # self.plot=Plot(self.pd, padding=50, fill_padding=True, # bgcolor="white", use_backbuffer=True, unified_draw=True) # xgrid, ygrid = meshgrid(x, y) # # color_plot=self.plot.img_plot('z', name="img_plot", xbounds=xgrid, ybounds=ygrid)[0] # self._image_index = color_plot.index #GridDataSource(xdata=x, ydata=y, sort_order=("ascending","ascending")) # self._image_index.on_trait_change(self._metadata_changed, "metadata_changed") # self._image_value=color_plot.value # self.value_range=DataRange1D(self._image_value) # color_plot.color_mapper = jet(self.value_range) # color_plot.tools.append(PanTool(color_plot, # constrain_key="shift")) # color_plot.overlays.append(ZoomTool(component=color_plot, # tool_mode="box", always_on=False)) # # color_plot.overlays.append(LineInspector(component=color_plot, # axis='index_x', # inspect_mode="indexed", # write_metadata=True, # is_listener=True, # color="white")) # # color_plot.overlays.append(LineInspector(component=color_plot, # axis='index_y', # inspect_mode="indexed", # write_metadata=True, # color="white", # is_listener=True)) # # cbar_index_mapper = LinearMapper(range=self.value_range) # self.colorbar = ColorBar(index_mapper=cbar_index_mapper, # plot=color_plot, # padding_top=color_plot.padding_top, # padding_bottom=color_plot.padding_bottom, # padding_right=40, # resizable='v', # width=30)#, ytitle="Magvec (mV)") # # #create horizontal line plot # self.horiz_cross_plot = Plot(self.pd, resizable="h", height=100, padding=50) # self.horiz_cross_plot.plot(("x", "horiz"))#, # self.horiz_cross_plot.index_range = color_plot.index_range.x_range # # #create vertical line plot # self.vert_cross_plot = Plot(self.pd, width = 100, orientation="v", # resizable="v", padding=50, padding_bottom=250) # self.vert_cross_plot.plot(("y", "vert")) # self.vert_cross_plot.index_range = color_plot.index_range.y_range # #self.vert_cross_plot.x_axis.tick_label_formatter = lambda x: '%.2g'%x # self.color_plot=color_plot # # self.container = HPlotContainer(padding=40, fill_padding=True, # bgcolor = "white", use_backbuffer=False) # inner_cont = VPlotContainer(padding=0, use_backbuffer=True) # inner_cont.add(self.horiz_cross_plot) # inner_cont.add(self.plot) # self.container.add(self.colorbar) # self.container.add(inner_cont) # self.container.add(self.vert_cross_plot) # #self.vert_cross_plot.y_axis.title="Frequency" # #self.horiz_cross_plot.x_axis.title="Time (us)" # # def _metadata_changed(self, old, new): # if self._image_index.metadata.has_key("selections"): # x_ndx, y_ndx = self._image_index.metadata["selections"] # if y_ndx and x_ndx: # self.pd.set_data("horiz", self._image_value.data[y_ndx,:]) # self.pd.set_data("vert", self._image_value.data[:,x_ndx]) # #class Line_Plot(HasTraits): # plot_control=Instance(Plot_Control) # request_redraw=DelegatesTo('plot_control') # new_plot=DelegatesTo('plot_control') # xtitle=DelegatesTo('plot_control') # ytitle=DelegatesTo('plot_control') # title=DelegatesTo('plot_control') # show_legend=DelegatesTo('plot_control') # xyformat=DelegatesTo('plot_control') # plot=Instance(Plot) # keymap=DelegatesTo('plot_control') #Dict() # color_index=Int() # mycolors=List([ 'blue', 'red', 'green', 'purple', 'black', 'darkgray', 'cyan', 'magenta', 'orange']) # value_scale=DelegatesTo('plot_control') # index_scale=DelegatesTo('plot_control') # xcomplex=DelegatesTo('plot_control') # ycomplex=DelegatesTo('plot_control') # # xkeys=DelegatesTo('plot_control') # zkeys=DelegatesTo('plot_control') # xindices=DelegatesTo('plot_control') # zindices=DelegatesTo('plot_control') # pd = Instance(ArrayPlotData) # # def _value_scale_changed(self): # #if self.color_index!=0: # self.plot.value_scale = self.value_scale # self.plot.request_redraw() # # def _index_scale_changed(self): # #if self.color_index!=0: # self.plot.index_scale = self.index_scale # self.plot.request_redraw() # # def _show_legend_changed(self): # self.plot.legend.visible = self.show_legend # self.plot.request_redraw() # # def _title_changed(self): # self.plot.title = self.title # self.plot.request_redraw() # # def _xtitle_changed(self): # self.plot.x_axis.title=self.xtitle # self.plot.request_redraw() # # def _ytitle_changed(self): # self.plot.y_axis.title=self.ytitle # self.plot.request_redraw() # # def _request_redraw_fired(self): # self.plot.request_redraw() # # def _new_plot_fired(self): # for key in self.plot.plots.keys(): # self.remove_plot(key) # self.color_index=0 # for n, name in enumerate(self.zkeys): # key='z'+str(name) # self.add_plot(key) # # def _zkeys_changed(self, name, old, new): # #print self.pd.list_data() # n=0 # for key in self.pd.list_data(): # if int(key[1:]) in new: # self.add_plot(key) # n=n+1 # else: # self.remove_plot(key) # ## for key, plot in self.plot.plots.iteritems(): ## if int(key[1:]) in new: ## if self.xyformat.t_color=="transparent" or self.xyformat.t_color==(1.0, 1.0, 1.0, 1.0) : ## color=self.mycolors[mod(n, len(self.mycolors))] ## else: ## color=self.xyformat.t_color ## plot[0].color=color ## #plot[0].outline_color=self.xyformat.outline_color, ## n=n+1 ## ## else: ## plot[0].color="none" # #plot[0].outline_color="none" # # def add_plot(self, key, z, xkey='x0', x=None): # if key not in self.plot.plots.keys() and key[0]!='x': # if self.xyformat.t_color=="transparent" or self.xyformat.t_color==(1.0, 1.0, 1.0, 1.0) : # color=self.mycolors[mod(self.color_index, len(self.mycolors))] # else: # color=self.xyformat.t_color # # if x!=None: # self.pd.set_data(xkey, x) # self.pd.set_data(key, z) # # #if self.color_index<len(self.xkeys): # # xkey='x'+str(self.xkeys[self.color_index]) # #else: # # xkey='x'+str(self.xkeys[0]) # self.plot.plot((xkey, key), # name=key, # type=self.xyformat.plot_type, # line_width=self.xyformat.line_width, # color=color, # outline_color=self.xyformat.outline_color, # marker = self.xyformat.marker, # marker_size = self.xyformat.marker_size) # self.color_index=self.color_index+1 # # def remove_plot(self, key): # if key in self.plot.plots.keys(): # self.plot.delplot(key) # # def __init__(self, data, plot_control, *args, **kws): # super(Line_Plot, self).__init__(*args, **kws) # self.plot_control=plot_control # self.pd = ArrayPlotData() # # for name, arr in sorted(data['z'].iteritems()): # self.pd.set_data('z'+str(name), arr) # # for name, arr in sorted(data['x'].iteritems()): # self.pd.set_data('x'+str(name), arr) # # plot = Plot(self.pd, padding=50, fill_padding=True, # bgcolor="white", use_backbuffer=True) # # # Attach some tools to the plot # plot.tools.append(PanTool(plot)) # zoom = ZoomTool(component=plot, tool_mode="box", always_on=False) # plot.overlays.append(zoom) # plot.legend.tools.append(LegendTool(plot.legend, drag_button="right")) # self.plot=plot # # for n, item in enumerate(self.zkeys): # key='z'+str(item) # if self.xyformat.t_color=="transparent" or self.xyformat.t_color==(1.0, 1.0, 1.0, 1.0) : # color=self.mycolors[mod(n, len(self.mycolors))] # else: # color=self.xyformat.t_color # if n<len(self.xkeys): # xkey='x'+str(self.xkeys[n]) # else: # xkey='x'+str(self.xkeys[0]) # #n=n+1 # #self.pd.set_data(key, magphase(self._image_value.data[int(item)], self.ycomplex)) # self.plot.plot((xkey, key), # name=key, # type=self.xyformat.plot_type, # line_width=self.xyformat.line_width, # color=color, # outline_color=self.xyformat.outline_color, # marker = self.xyformat.marker, # marker_size = self.xyformat.marker_size) # self.plot.value_scale = self.value_scale # self.plot.index_scale= self.index_scale # # # traits_view = View(Item('plot', style='custom',editor=ComponentEditor(), # show_label=False), # resizable=True, title="Chaco Plot", # width=800, height=700, #kind='modal', # buttons=[OKButton, CancelButton] # )
class SpectrumAnalyzerView(HasTraits): python_console_cmds = Dict() plot = Instance(Plot) plot_data = Instance(ArrayPlotData) which_plot = Str("Channel 1") hint = Str("Enable with setting in \"System Monitor\" group.") traits_view = View( Item( 'plot', editor=ComponentEditor(bgcolor=(0.8, 0.8, 0.8)), show_label=False), HGroup( Spring(width=20, springy=False), Item( '', label='Channel Selection:', emphasized=True), Item( name='which_plot', show_label=False, tooltip='Select the RF Channel for which to display Spectrum Analyzer', editor=EnumEditor( values=["Channel 1", "Channel 2", "Channel 3", "Channel 4"])), Spring(width=20, springy=True), Item('hint', show_label=False, style='readonly', style_sheet='*{font-style:italic}'), Spring(width=20, springy=True))) def parse_payload(self, raw_payload): """ Params ====== payload: is an array of ints representing bytes from the SBP_MSG_USER_DATA message 'contents' Returns ======= JSON dict of a payload based on this format, except all N of the diff_amplitude are together in a list under 'diff_amplitudes' and rx_time is split into TOW and week Frequency is in Hz, Amplitude is in dB FIELD TYPE OFFSET SHORT EXPLANATION user_msg_tag u16 0 bespoke preamble for spectrum message rx_time struct 2 struct gps_time_t defined as double TOW + s16 WEEK starting_frequency float 12 starting frequency for this packet frequency_step float 16 frequency step for points in this packet min_amplitude float 20 minimum level of amplitude amplitude_step float 24 amplitude unit diff_amplitude u8 28 N values in the above units """ # Turn the array of ints representing uint8 bytes back to binary, so you can use struct # formatting to unpack it. Otherwise you would have to manually parse each byte. pack_fmt_str = 'B' * len(raw_payload) payload = struct.pack(pack_fmt_str, *raw_payload) payload_header_fmt_str = '<Hdhffff' payload_header_bytes = struct.calcsize(payload_header_fmt_str) diff_amplitude_n = (len(raw_payload) - payload_header_bytes) diff_amplitude_fmt_str = 'B' * diff_amplitude_n fmt_str = payload_header_fmt_str + diff_amplitude_fmt_str parsed_payload = struct.unpack(fmt_str, payload) fft_msg_header = [ 'user_msg_tag', 'TOW', 'week', 'starting_frequency', 'frequency_step', 'min_amplitude', 'amplitude_step' ] payload_json = dict( zip(fft_msg_header, parsed_payload[:len(fft_msg_header)])) fft_msg_payload = parsed_payload[len(fft_msg_header):] payload_json['diff_amplitudes'] = fft_msg_payload return payload_json def _which_plot_changed(self): channel = int(self.which_plot[-1:]) self.fftmonitor.enable_channel(channel) self.fftmonitor.disable_channel([ch for ch in CHANNELS if ch != channel]) def spectrum_analyzer_state_callback(self, sbp_msg, **metadata): ''' Params ====== sbp_msg: sbp.msg.SBP object Updates the view's data for use in self.update_plot ''' self.fftmonitor.capture_fft(sbp_msg, **metadata) channel = int(self.which_plot[-1:]) if self.fftmonitor.num_ffts(channel) > 0: most_recent_fft = self.fftmonitor.get_ffts(channel).pop() self.fftmonitor.clear_ffts() self.most_recent_complete_data['frequencies'] = most_recent_fft['frequencies'] self.most_recent_complete_data['amplitudes'] = most_recent_fft['amplitudes'] self.update_scheduler.schedule_update('update_plot', self.update_plot) def update_plot(self): most_recent_fft = self.most_recent_complete_data if len(most_recent_fft['frequencies']) != 0: self.plot_data.set_data('frequency', most_recent_fft['frequencies']) self.plot_data.set_data('amplitude', most_recent_fft['amplitudes']) self.plot.value_mapper.range.low = min( most_recent_fft['amplitudes']) self.plot.value_mapper.range.high = max( most_recent_fft['amplitudes']) def __init__(self, link): super(SpectrumAnalyzerView, self).__init__() self.link = link self.link.add_callback(self.spectrum_analyzer_state_callback, [SBP_MSG_SPECAN, SBP_MSG_SPECAN_DEP]) self.python_console_cmds = {'spectrum': self} self.fftmonitor = FFTMonitor() self.fftmonitor.enable_channel(int(self.which_plot[-1:])) self.most_recent_complete_data = { 'frequencies': np.array([]), 'amplitudes': np.array([]) } self.plot_data = ArrayPlotData() self.plot = Plot(self.plot_data, emphasized=True) self.plot.title = 'Spectrum Analyzer' self.plot.title_color = [0, 0, 0.43] self.plot.value_axis.orientation = 'right' self.plot.value_axis.title_spacing = 30 self.plot.value_axis.title = 'Amplitude (dB)' self.plot.index_axis.title = 'Frequency (MHz)' self.plot_data.set_data('frequency', [0]) self.plot_data.set_data('amplitude', [0]) self.plot.plot( ('frequency', 'amplitude'), type='line', name='spectrum') self.update_scheduler = UpdateScheduler()
class SolutionView(HasTraits): python_console_cmds = Dict() # we need to doubleup on Lists to store the psuedo absolutes separately # without rewriting everything """ logging_v : toggle logging for velocity files directory_name_v : location and name of velocity files logging_p : toggle logging for position files directory_name_p : location and name of velocity files """ plot_history_max = Int(1000) logging_v = Bool(False) directory_name_v = File logging_p = Bool(False) directory_name_p = File lats_psuedo_abs = List() lngs_psuedo_abs = List() alts_psuedo_abs = List() table = List() dops_table = List() pos_table = List() vel_table = List() rtk_pos_note = Str( "It is necessary to enter the \"Surveyed Position\" settings for the base station in order to view the RTK Positions in this tab." ) plot = Instance(Plot) plot_data = Instance(ArrayPlotData) # Store plots we care about for legend running = Bool(True) zoomall = Bool(False) position_centered = Bool(False) clear_button = SVGButton(label='', tooltip='Clear', filename=os.path.join(determine_path(), 'images', 'iconic', 'x.svg'), width=16, height=16) zoomall_button = SVGButton(label='', tooltip='Zoom All', toggle=True, filename=os.path.join(determine_path(), 'images', 'iconic', 'fullscreen.svg'), width=16, height=16) center_button = SVGButton(label='', tooltip='Center on Solution', toggle=True, filename=os.path.join(determine_path(), 'images', 'iconic', 'target.svg'), width=16, height=16) paused_button = SVGButton(label='', tooltip='Pause', toggle_tooltip='Run', toggle=True, filename=os.path.join(determine_path(), 'images', 'iconic', 'pause.svg'), toggle_filename=os.path.join( determine_path(), 'images', 'iconic', 'play.svg'), width=16, height=16) traits_view = View( HSplit( VGroup( Item('table', style='readonly', editor=TabularEditor(adapter=SimpleAdapter()), show_label=False, width=0.3), Item('rtk_pos_note', show_label=False, resizable=True, editor=MultilineTextEditor(TextEditor(multi_line=True)), style='readonly', width=0.3, height=-40), ), VGroup( HGroup( Item('paused_button', show_label=False), Item('clear_button', show_label=False), Item('zoomall_button', show_label=False), Item('center_button', show_label=False), ), Item('plot', show_label=False, editor=ComponentEditor(bgcolor=(0.8, 0.8, 0.8))), ))) def _zoomall_button_fired(self): self.zoomall = not self.zoomall def _center_button_fired(self): self.position_centered = not self.position_centered def _paused_button_fired(self): self.running = not self.running def _reset_remove_current(self): self.plot_data.set_data('cur_lat_spp', []) self.plot_data.set_data('cur_lng_spp', []) self.plot_data.set_data('cur_alt_spp', []) self.plot_data.set_data('cur_lat_dgnss', []) self.plot_data.set_data('cur_lng_dgnss', []) self.plot_data.set_data('cur_alt_dgnss', []) self.plot_data.set_data('cur_lat_float', []) self.plot_data.set_data('cur_lng_float', []) self.plot_data.set_data('cur_alt_float', []) self.plot_data.set_data('cur_lat_fixed', []) self.plot_data.set_data('cur_lng_fixed', []) self.plot_data.set_data('cur_alt_fixed', []) def _clear_history(self): self.plot_data.set_data('lat_spp', []) self.plot_data.set_data('lng_spp', []) self.plot_data.set_data('alt_spp', []) self.plot_data.set_data('lat_dgnss', []) self.plot_data.set_data('lng_dgnss', []) self.plot_data.set_data('alt_dgnss', []) self.plot_data.set_data('lat_float', []) self.plot_data.set_data('lng_float', []) self.plot_data.set_data('alt_float', []) self.plot_data.set_data('lat_fixed', []) self.plot_data.set_data('lng_fixed', []) self.plot_data.set_data('alt_fixed', []) def _clear_button_fired(self): self.tows = np.empty(self.plot_history_max) self.lats = np.empty(self.plot_history_max) self.lngs = np.empty(self.plot_history_max) self.alts = np.empty(self.plot_history_max) self.modes = np.empty(self.plot_history_max) self._clear_history() self._reset_remove_current() def _pos_llh_callback(self, sbp_msg, **metadata): # Updating an ArrayPlotData isn't thread safe (see chaco issue #9), so # actually perform the update in the UI thread. if self.running: GUI.invoke_later(self.pos_llh_callback, sbp_msg) def age_corrections_callback(self, sbp_msg, **metadata): age_msg = MsgAgeCorrections(sbp_msg) if age_msg.age != 0xFFFF: self.age_corrections = age_msg.age / 10.0 else: self.age_corrections = None def update_table(self): self._table_list = self.table_spp.items() def auto_survey(self): if self.last_soln.flags != 0: self.latitude_list.append(self.last_soln.lat) self.longitude_list.append(self.last_soln.lon) self.altitude_list.append(self.last_soln.height) if len(self.latitude_list) > 1000: self.latitude_list = self.latitude_list[-1000:] self.longitude_list = self.longitude_list[-1000:] self.altitude_list = self.altitude_list[-1000:] if len(self.latitude_list) != 0: self.latitude = sum(self.latitude_list) / len(self.latitude_list) self.altitude = sum(self.altitude_list) / len(self.latitude_list) self.longitude = sum(self.longitude_list) / len(self.latitude_list) def pos_llh_callback(self, sbp_msg, **metadata): if sbp_msg.msg_type == SBP_MSG_POS_LLH_DEP_A: soln = MsgPosLLHDepA(sbp_msg) else: soln = MsgPosLLH(sbp_msg) self.last_soln = soln self.last_pos_mode = get_mode(soln) pos_table = [] soln.h_accuracy *= 1e-3 soln.v_accuracy *= 1e-3 tow = soln.tow * 1e-3 if self.nsec is not None: tow += self.nsec * 1e-9 # Return the best estimate of my local and receiver time in convenient # format that allows changing precision of the seconds ((tloc, secloc), (tgps, secgps)) = log_time_strings(self.week, tow) if self.utc_time: ((tutc, secutc)) = datetime_2_str(self.utc_time) if (self.directory_name_p == ''): filepath_p = time.strftime("position_log_%Y%m%d-%H%M%S.csv") else: filepath_p = os.path.join( self.directory_name_p, time.strftime("position_log_%Y%m%d-%H%M%S.csv")) if self.logging_p == False: self.log_file = None if self.logging_p: if self.log_file is None: self.log_file = sopen(filepath_p, 'w') self.log_file.write( "pc_time,gps_time,tow(msec),latitude(degrees),longitude(degrees),altitude(meters)," "h_accuracy(meters),v_accuracy(meters),n_sats,flags\n") log_str_gps = "" if tgps != "" and secgps != 0: log_str_gps = "{0}:{1:06.6f}".format(tgps, float(secgps)) self.log_file.write( '%s,%s,%.3f,%.10f,%.10f,%.4f,%.4f,%.4f,%d,%d\n' % ("{0}:{1:06.6f}".format(tloc, float(secloc)), log_str_gps, tow, soln.lat, soln.lon, soln.height, soln.h_accuracy, soln.v_accuracy, soln.n_sats, soln.flags)) self.log_file.flush() if self.last_pos_mode == 0: pos_table.append(('GPS Week', EMPTY_STR)) pos_table.append(('GPS TOW', EMPTY_STR)) pos_table.append(('GPS Time', EMPTY_STR)) pos_table.append(('Num. Signals', EMPTY_STR)) pos_table.append(('Lat', EMPTY_STR)) pos_table.append(('Lng', EMPTY_STR)) pos_table.append(('Height', EMPTY_STR)) pos_table.append(('Horiz Acc', EMPTY_STR)) pos_table.append(('Vert Acc', EMPTY_STR)) else: self.last_stime_update = time.time() if self.week is not None: pos_table.append(('GPS Week', str(self.week))) pos_table.append(('GPS TOW', "{:.3f}".format(tow))) if self.week is not None: pos_table.append( ('GPS Time', "{0}:{1:06.3f}".format(tgps, float(secgps)))) if self.utc_time is not None: pos_table.append( ('UTC Time', "{0}:{1:06.3f}".format(tutc, float(secutc)))) pos_table.append(('UTC Src', self.utc_source)) if self.utc_time is None: pos_table.append(('UTC Time', EMPTY_STR)) pos_table.append(('UTC Src', EMPTY_STR)) pos_table.append(('Sats Used', soln.n_sats)) pos_table.append(('Lat', soln.lat)) pos_table.append(('Lng', soln.lon)) pos_table.append(('Height', soln.height)) pos_table.append(('Horiz Acc', soln.h_accuracy)) pos_table.append(('Vert Acc', soln.v_accuracy)) pos_table.append(('Pos Flags', '0x%03x' % soln.flags)) pos_table.append(('Pos Fix Mode', mode_dict[self.last_pos_mode])) if self.age_corrections != None: pos_table.append(('Corr. Age [s]', self.age_corrections)) self.auto_survey() # setup_plot variables self.lats[1:] = self.lats[:-1] self.lngs[1:] = self.lngs[:-1] self.alts[1:] = self.alts[:-1] self.tows[1:] = self.tows[:-1] self.modes[1:] = self.modes[:-1] self.lats[0] = soln.lat self.lngs[0] = soln.lon self.alts[0] = soln.height self.tows[0] = soln.tow self.modes[0] = self.last_pos_mode self.lats = self.lats[-self.plot_history_max:] self.lngs = self.lngs[-self.plot_history_max:] self.alts = self.alts[-self.plot_history_max:] self.tows = self.tows[-self.plot_history_max:] self.modes = self.modes[-self.plot_history_max:] # SPP spp_indexer, dgnss_indexer, float_indexer, fixed_indexer = None, None, None, None self._clear_history() if np.any(self.modes): spp_indexer = (self.modes == SPP_MODE) dgnss_indexer = (self.modes == DGNSS_MODE) float_indexer = (self.modes == FLOAT_MODE) fixed_indexer = (self.modes == FIXED_MODE) # make sure that there is at least one true in indexer before setting if any(spp_indexer): self.plot_data.set_data('lat_spp', self.lats[spp_indexer]) self.plot_data.set_data('lng_spp', self.lngs[spp_indexer]) self.plot_data.set_data('alt_spp', self.alts[spp_indexer]) if any(dgnss_indexer): self.plot_data.set_data('lat_dgnss', self.lats[dgnss_indexer]) self.plot_data.set_data('lng_dgnss', self.lngs[dgnss_indexer]) self.plot_data.set_data('alt_dgnss', self.alts[dgnss_indexer]) if any(float_indexer): self.plot_data.set_data('lat_float', self.lats[float_indexer]) self.plot_data.set_data('lng_float', self.lngs[float_indexer]) self.plot_data.set_data('alt_float', self.alts[float_indexer]) if any(fixed_indexer): self.plot_data.set_data('lat_fixed', self.lats[fixed_indexer]) self.plot_data.set_data('lng_fixed', self.lngs[fixed_indexer]) self.plot_data.set_data('alt_fixed', self.alts[fixed_indexer]) # update our "current solution" icon if self.last_pos_mode == SPP_MODE: self._reset_remove_current() self.plot_data.set_data('cur_lat_spp', [soln.lat]) self.plot_data.set_data('cur_lng_spp', [soln.lon]) elif self.last_pos_mode == DGNSS_MODE: self._reset_remove_current() self.plot_data.set_data('cur_lat_dgnss', [soln.lat]) self.plot_data.set_data('cur_lng_dgnss', [soln.lon]) elif self.last_pos_mode == FLOAT_MODE: self._reset_remove_current() self.plot_data.set_data('cur_lat_float', [soln.lat]) self.plot_data.set_data('cur_lng_float', [soln.lon]) elif self.last_pos_mode == FIXED_MODE: self._reset_remove_current() self.plot_data.set_data('cur_lat_fixed', [soln.lat]) self.plot_data.set_data('cur_lng_fixed', [soln.lon]) else: pass # set-up table variables self.pos_table = pos_table self.table = self.pos_table + self.vel_table + self.dops_table # TODO: figure out how to center the graph now that we have two separate messages # when we selectively send only SPP, the centering function won't work anymore if not self.zoomall and self.position_centered: d = (self.plot.index_range.high - self.plot.index_range.low) / 2. self.plot.index_range.set_bounds(soln.lon - d, soln.lon + d) d = (self.plot.value_range.high - self.plot.value_range.low) / 2. self.plot.value_range.set_bounds(soln.lat - d, soln.lat + d) if self.zoomall: plot_square_axes( self.plot, ('lng_spp', 'lng_dgnss', 'lng_float', 'lng_fixed'), ('lat_spp', 'lat_dgnss', 'lat_float', 'lat_fixed')) def dops_callback(self, sbp_msg, **metadata): flags = 0 if sbp_msg.msg_type == SBP_MSG_DOPS_DEP_A: dops = MsgDopsDepA(sbp_msg) flags = 1 else: dops = MsgDops(sbp_msg) flags = dops.flags if flags != 0: self.dops_table = [('PDOP', '%.1f' % (dops.pdop * 0.01)), ('GDOP', '%.1f' % (dops.gdop * 0.01)), ('TDOP', '%.1f' % (dops.tdop * 0.01)), ('HDOP', '%.1f' % (dops.hdop * 0.01)), ('VDOP', '%.1f' % (dops.vdop * 0.01))] else: self.dops_table = [('PDOP', EMPTY_STR), ('GDOP', EMPTY_STR), ('TDOP', EMPTY_STR), ('HDOP', EMPTY_STR), ('VDOP', EMPTY_STR)] self.dops_table.append(('DOPS Flags', '0x%03x' % flags)) self.table = self.pos_table + self.vel_table + self.dops_table def vel_ned_callback(self, sbp_msg, **metadata): flags = 0 if sbp_msg.msg_type == SBP_MSG_VEL_NED_DEP_A: vel_ned = MsgVelNEDDepA(sbp_msg) flags = 1 else: vel_ned = MsgVelNED(sbp_msg) flags = vel_ned.flags tow = vel_ned.tow * 1e-3 if self.nsec is not None: tow += self.nsec * 1e-9 ((tloc, secloc), (tgps, secgps)) = log_time_strings(self.week, tow) if self.directory_name_v == '': filepath_v = time.strftime("velocity_log_%Y%m%d-%H%M%S.csv") else: filepath_v = os.path.join( self.directory_name_v, time.strftime("velocity_log_%Y%m%d-%H%M%S.csv")) if self.logging_v == False: self.vel_log_file = None if self.logging_v: if self.vel_log_file is None: self.vel_log_file = sopen(filepath_v, 'w') self.vel_log_file.write( 'pc_time,gps_time,tow,north(m/s),east(m/s),down(m/s),speed(m/s),flags,num_signals\n' ) log_str_gps = '' if tgps != "" and secgps != 0: log_str_gps = "{0}:{1:06.6f}".format(tgps, float(secgps)) self.vel_log_file.write( '%s,%s,%.3f,%.6f,%.6f,%.6f,%.6f,%d,%d\n' % ("{0}:{1:06.6f}".format(tloc, float(secloc)), log_str_gps, tow, vel_ned.n * 1e-3, vel_ned.e * 1e-3, vel_ned.d * 1e-3, math.sqrt(vel_ned.n * vel_ned.n + vel_ned.e * vel_ned.e) * 1e-3, flags, vel_ned.n_sats)) self.vel_log_file.flush() if flags != 0: self.vel_table = [ ('Vel. N', '% 8.4f' % (vel_ned.n * 1e-3)), ('Vel. E', '% 8.4f' % (vel_ned.e * 1e-3)), ('Vel. D', '% 8.4f' % (vel_ned.d * 1e-3)), ] else: self.vel_table = [ ('Vel. N', EMPTY_STR), ('Vel. E', EMPTY_STR), ('Vel. D', EMPTY_STR), ] self.vel_table.append(('Vel Flags', '0x%03x' % flags)) self.table = self.pos_table + self.vel_table + self.dops_table def gps_time_callback(self, sbp_msg, **metadata): if sbp_msg.msg_type == SBP_MSG_GPS_TIME_DEP_A: time_msg = MsgGPSTimeDepA(sbp_msg) flags = 1 elif sbp_msg.msg_type == SBP_MSG_GPS_TIME: time_msg = MsgGPSTime(sbp_msg) flags = time_msg.flags if flags != 0: self.week = time_msg.wn self.nsec = time_msg.ns_residual def utc_time_callback(self, sbp_msg, **metadata): tmsg = MsgUtcTime(sbp_msg) seconds = math.floor(tmsg.seconds) microseconds = int(tmsg.ns / 1000.00) if tmsg.flags & 0x1 == 1: dt = datetime.datetime(tmsg.year, tmsg.month, tmsg.day, tmsg.hours, tmsg.minutes, tmsg.seconds, microseconds) self.utc_time = dt self.utc_time_flags = tmsg.flags if (tmsg.flags >> 3) & 0x3 == 0: self.utc_source = "Factory Default" elif (tmsg.flags >> 3) & 0x3 == 1: self.utc_source = "Non Volatile Memory" elif (tmsg.flags >> 3) & 0x3 == 2: self.utc_source = "Decoded this Session" else: self.utc_source = "Unknown" else: self.utc_time = None self.utc_source = None def __init__(self, link, dirname=''): super(SolutionView, self).__init__() self.lats = np.zeros(self.plot_history_max) self.lngs = np.zeros(self.plot_history_max) self.alts = np.zeros(self.plot_history_max) self.tows = np.zeros(self.plot_history_max) self.modes = np.zeros(self.plot_history_max) self.log_file = None self.directory_name_v = dirname self.directory_name_p = dirname self.vel_log_file = None self.last_stime_update = 0 self.last_soln = None self.counter = 0 self.latitude_list = [] self.longitude_list = [] self.altitude_list = [] self.altitude = 0 self.longitude = 0 self.latitude = 0 self.last_pos_mode = 0 self.plot_data = ArrayPlotData(lat_spp=[], lng_spp=[], alt_spp=[], cur_lat_spp=[], cur_lng_spp=[], lat_dgnss=[], lng_dgnss=[], alt_dgnss=[], cur_lat_dgnss=[], cur_lng_dgnss=[], lat_float=[], lng_float=[], alt_float=[], cur_lat_float=[], cur_lng_float=[], lat_fixed=[], lng_fixed=[], alt_fixed=[], cur_lat_fixed=[], cur_lng_fixed=[]) self.plot = Plot(self.plot_data) # 1000 point buffer self.plot.plot(('lng_spp', 'lat_spp'), type='line', line_width=0.1, name='', color=color_dict[SPP_MODE]) self.plot.plot(('lng_spp', 'lat_spp'), type='scatter', name='', color=color_dict[SPP_MODE], marker='dot', line_width=0.0, marker_size=1.0) self.plot.plot(('lng_dgnss', 'lat_dgnss'), type='line', line_width=0.1, name='', color=color_dict[DGNSS_MODE]) self.plot.plot(('lng_dgnss', 'lat_dgnss'), type='scatter', name='', color=color_dict[DGNSS_MODE], marker='dot', line_width=0.0, marker_size=1.0) self.plot.plot(('lng_float', 'lat_float'), type='line', line_width=0.1, name='', color=color_dict[FLOAT_MODE]) self.plot.plot(('lng_float', 'lat_float'), type='scatter', name='', color=color_dict[FLOAT_MODE], marker='dot', line_width=0.0, marker_size=1.0) self.plot.plot(('lng_fixed', 'lat_fixed'), type='line', line_width=0.1, name='', color=color_dict[FIXED_MODE]) self.plot.plot(('lng_fixed', 'lat_fixed'), type='scatter', name='', color=color_dict[FIXED_MODE], marker='dot', line_width=0.0, marker_size=1.0) # current values spp = self.plot.plot(('cur_lng_spp', 'cur_lat_spp'), type='scatter', name=mode_dict[SPP_MODE], color=color_dict[SPP_MODE], marker='plus', line_width=1.5, marker_size=5.0) dgnss = self.plot.plot(('cur_lng_dgnss', 'cur_lat_dgnss'), type='scatter', name=mode_dict[DGNSS_MODE], color=color_dict[DGNSS_MODE], marker='plus', line_width=1.5, marker_size=5.0) rtkfloat = self.plot.plot(('cur_lng_float', 'cur_lat_float'), type='scatter', name=mode_dict[FLOAT_MODE], color=color_dict[FLOAT_MODE], marker='plus', line_width=1.5, marker_size=5.0) rtkfix = self.plot.plot(('cur_lng_fixed', 'cur_lat_fixed'), type='scatter', name=mode_dict[FIXED_MODE], color=color_dict[FIXED_MODE], marker='plus', line_width=1.5, marker_size=5.0) plot_labels = ['SPP', 'DGPS', "RTK float", "RTK fixed"] plots_legend = dict(zip(plot_labels, [spp, dgnss, rtkfloat, rtkfix])) self.plot.legend.plots = plots_legend self.plot.legend.labels = plot_labels # sets order self.plot.legend.visible = True self.plot.index_axis.tick_label_position = 'inside' self.plot.index_axis.tick_label_color = 'gray' self.plot.index_axis.tick_color = 'gray' self.plot.index_axis.title = 'Longitude (degrees)' self.plot.index_axis.title_spacing = 5 self.plot.value_axis.tick_label_position = 'inside' self.plot.value_axis.tick_label_color = 'gray' self.plot.value_axis.tick_color = 'gray' self.plot.value_axis.title = 'Latitude (degrees)' self.plot.value_axis.title_spacing = 5 self.plot.padding = (25, 25, 25, 25) self.plot.tools.append(PanTool(self.plot)) zt = ZoomTool(self.plot, zoom_factor=1.1, tool_mode="box", always_on=False) self.plot.overlays.append(zt) self.link = link self.link.add_callback(self._pos_llh_callback, [SBP_MSG_POS_LLH_DEP_A, SBP_MSG_POS_LLH]) self.link.add_callback(self.vel_ned_callback, [SBP_MSG_VEL_NED_DEP_A, SBP_MSG_VEL_NED]) self.link.add_callback(self.dops_callback, [SBP_MSG_DOPS_DEP_A, SBP_MSG_DOPS]) self.link.add_callback(self.gps_time_callback, [SBP_MSG_GPS_TIME_DEP_A, SBP_MSG_GPS_TIME]) self.link.add_callback(self.utc_time_callback, [SBP_MSG_UTC_TIME]) self.link.add_callback(self.age_corrections_callback, SBP_MSG_AGE_CORRECTIONS) self.week = None self.utc_time = None self.age_corrections = None self.nsec = 0 self.python_console_cmds = { 'solution': self, }
class IMUView(HasTraits): python_console_cmds = Dict() plot = Instance(Plot) plot_data = Instance(ArrayPlotData) imu_temp = Float(0) imu_conf = Int(0) rms_acc_x = Float(0) rms_acc_y = Float(0) rms_acc_z = Float(0) traits_view = View( VGroup( Item('plot', editor=ComponentEditor(bgcolor=(0.8, 0.8, 0.8)), show_label=False), HGroup( Item('imu_temp', format_str='%.2f C', height=-16, width=4), Item('imu_conf', format_str='0x%02X', height=-16, width=4), Item('rms_acc_x', format_str='%.2f g', height=-16, width=4), Item('rms_acc_y', format_str='%.2f g', height=-16, width=4), Item('rms_acc_z', format_str='%.2f g', height=-16, width=4), ), )) def update_plot(self): self.last_plot_update_time = monotonic() self.plot_data.set_data('acc_x', self.acc_x) self.plot_data.set_data('acc_y', self.acc_y) self.plot_data.set_data('acc_z', self.acc_z) self.plot_data.set_data('gyr_x', self.gyro_x) self.plot_data.set_data('gyr_y', self.gyro_y) self.plot_data.set_data('gyr_z', self.gyro_z) def imu_set_data(self): if monotonic() - self.last_plot_update_time < GUI_UPDATE_PERIOD: return if self.imu_conf is not None: acc_range = self.imu_conf & 0xF sf = 2.**(acc_range + 1) / 2.**15 self.rms_acc_x = sf * np.sqrt(np.mean(np.square(self.acc_x))) self.rms_acc_y = sf * np.sqrt(np.mean(np.square(self.acc_y))) self.rms_acc_z = sf * np.sqrt(np.mean(np.square(self.acc_z))) self.update_scheduler.schedule_update('update_plot', self.update_plot) def imu_aux_callback(self, sbp_msg, **metadata): if sbp_msg.imu_type == 0: self.imu_temp = 23 + sbp_msg.temp / 2.**9 self.imu_conf = sbp_msg.imu_conf elif sbp_msg.imu_type == 1: self.imu_temp = 25.0 + sbp_msg.temp / 256.0 self.imu_conf = sbp_msg.imu_conf else: print("IMU type %d not known" % sbp_msg.imu_type) def imu_raw_callback(self, sbp_msg, **metadata): memoryview(self.acc_x)[:-1] = memoryview(self.acc_x)[1:] memoryview(self.acc_y)[:-1] = memoryview(self.acc_y)[1:] memoryview(self.acc_z)[:-1] = memoryview(self.acc_z)[1:] memoryview(self.gyro_x)[:-1] = memoryview(self.gyro_x)[1:] memoryview(self.gyro_y)[:-1] = memoryview(self.gyro_y)[1:] memoryview(self.gyro_z)[:-1] = memoryview(self.gyro_z)[1:] self.acc_x[-1] = sbp_msg.acc_x self.acc_y[-1] = sbp_msg.acc_y self.acc_z[-1] = sbp_msg.acc_z self.gyro_x[-1] = sbp_msg.gyr_x self.gyro_y[-1] = sbp_msg.gyr_y self.gyro_z[-1] = sbp_msg.gyr_z self.imu_set_data() def __init__(self, link): super(IMUView, self).__init__() self.acc_x = np.zeros(NUM_POINTS) self.acc_y = np.zeros(NUM_POINTS) self.acc_z = np.zeros(NUM_POINTS) self.gyro_x = np.zeros(NUM_POINTS) self.gyro_y = np.zeros(NUM_POINTS) self.gyro_z = np.zeros(NUM_POINTS) self.last_plot_update_time = 0 self.plot_data = ArrayPlotData(t=np.arange(NUM_POINTS), acc_x=[0.0], acc_y=[0.0], acc_z=[0.0], gyr_x=[0.0], gyr_y=[0.0], gyr_z=[0.0]) self.plot = Plot(self.plot_data, auto_colors=colours_list, emphasized=True) self.plot.title = 'Raw IMU Data' self.plot.title_color = [0, 0, 0.43] self.ylim = self.plot.value_mapper.range self.ylim.low = -32768 self.ylim.high = 32767 # self.plot.value_range.bounds_func = lambda l, h, m, tb: (0, h * (1 + m)) self.plot.value_axis.orientation = 'right' self.plot.value_axis.axis_line_visible = False self.plot.value_axis.title = 'LSB count' self.legend_visible = True self.plot.legend.visible = True self.plot.legend.align = 'll' self.plot.legend.line_spacing = 1 self.plot.legend.font = 'modern 8' self.plot.legend.draw_layer = 'overlay' self.plot.legend.tools.append( LegendTool(self.plot.legend, drag_button="right")) acc_x = self.plot.plot(('t', 'acc_x'), type='line', color='auto', name='Accn. X') acc_x = self.plot.plot(('t', 'acc_y'), type='line', color='auto', name='Accn. Y') acc_x = self.plot.plot(('t', 'acc_z'), type='line', color='auto', name='Accn. Z') acc_x = self.plot.plot(('t', 'gyr_x'), type='line', color='auto', name='Gyro X') acc_x = self.plot.plot(('t', 'gyr_y'), type='line', color='auto', name='Gyro Y') acc_x = self.plot.plot(('t', 'gyr_z'), type='line', color='auto', name='Gyro Z') self.link = link self.link.add_callback(self.imu_raw_callback, SBP_MSG_IMU_RAW) self.link.add_callback(self.imu_aux_callback, SBP_MSG_IMU_AUX) self.python_console_cmds = {'track': self} self.update_scheduler = UpdateScheduler()
class IMUView(HasTraits): python_console_cmds = Dict() plot = Instance(Plot) plot_data = Instance(ArrayPlotData) imu_temp = Float(0) imu_conf = Int(0) rms_acc_x = Float(0) rms_acc_y = Float(0) rms_acc_z = Float(0) traits_view = View( VGroup( Item( 'plot', editor=ComponentEditor(bgcolor=(0.8, 0.8, 0.8)), show_label=False, ), HGroup( Item('imu_temp', format_str='%.2f C'), Item('imu_conf', format_str='0x%02X'), Item('rms_acc_x', format_str='%.2f g'), Item('rms_acc_y', format_str='%.2f g'), Item('rms_acc_z', format_str='%.2f g'), ), )) def imu_aux_callback(self, sbp_msg, **metadata): if sbp_msg.imu_type == 0: self.imu_temp = 23 + sbp_msg.temp / 2.**9 self.imu_conf = sbp_msg.imu_conf else: print "IMU type %d not known" % sbp_msg.imu_type def imu_raw_callback(self, sbp_msg, **metadata): self.acc[:-1, :] = self.acc[1:, :] self.gyro[:-1, :] = self.gyro[1:, :] self.acc[-1] = (sbp_msg.acc_x, sbp_msg.acc_y, sbp_msg.acc_z) self.gyro[-1] = (sbp_msg.gyr_x, sbp_msg.gyr_y, sbp_msg.gyr_z) self.plot_data.set_data('acc_x', self.acc[:, 0]) self.plot_data.set_data('acc_y', self.acc[:, 1]) self.plot_data.set_data('acc_z', self.acc[:, 2]) self.plot_data.set_data('gyr_x', self.gyro[:, 0]) self.plot_data.set_data('gyr_y', self.gyro[:, 1]) self.plot_data.set_data('gyr_z', self.gyro[:, 2]) if self.imu_conf is not None: acc_range = self.imu_conf & 0xF sf = 2.**(acc_range + 1) / 2.**15 self.rms_acc_x = sf * np.sqrt(np.mean(np.square(self.acc[:, 0]))) self.rms_acc_y = sf * np.sqrt(np.mean(np.square(self.acc[:, 1]))) self.rms_acc_z = sf * np.sqrt(np.mean(np.square(self.acc[:, 2]))) def __init__(self, link): super(IMUView, self).__init__() self.acc = np.empty((NUM_POINTS, 3)) self.gyro = np.empty((NUM_POINTS, 3)) self.plot_data = ArrayPlotData(t=np.arange(NUM_POINTS), acc_x=[0.0], acc_y=[0.0], acc_z=[0.0], gyr_x=[0.0], gyr_y=[0.0], gyr_z=[0.0]) self.plot = Plot(self.plot_data, auto_colors=colours_list, emphasized=True) self.plot.title = 'Raw IMU Data' self.plot.title_color = [0, 0, 0.43] self.ylim = self.plot.value_mapper.range self.ylim.low = -32768 self.ylim.high = 32767 #self.plot.value_range.bounds_func = lambda l, h, m, tb: (0, h * (1 + m)) self.plot.value_axis.orientation = 'right' self.plot.value_axis.axis_line_visible = False self.plot.value_axis.title = 'LSB count' self.legend_visible = True self.plot.legend.visible = True self.plot.legend.align = 'll' self.plot.legend.line_spacing = 1 self.plot.legend.font = 'modern 8' self.plot.legend.draw_layer = 'overlay' self.plot.legend.tools.append( LegendTool(self.plot.legend, drag_button="right")) acc_x = self.plot.plot(('t', 'acc_x'), type='line', color='auto', name='Accn. X') acc_x = self.plot.plot(('t', 'acc_y'), type='line', color='auto', name='Accn. Y') acc_x = self.plot.plot(('t', 'acc_z'), type='line', color='auto', name='Accn. Z') acc_x = self.plot.plot(('t', 'gyr_x'), type='line', color='auto', name='Gyro X') acc_x = self.plot.plot(('t', 'gyr_y'), type='line', color='auto', name='Gyro Y') acc_x = self.plot.plot(('t', 'gyr_z'), type='line', color='auto', name='Gyro Z') self.link = link self.link.add_callback(self.imu_raw_callback, SBP_MSG_IMU_RAW) self.link.add_callback(self.imu_aux_callback, SBP_MSG_IMU_AUX) self.python_console_cmds = {'track': self}