def add_default_axes(plot, orientation="normal", vtitle="", htitle=""): """ Creates left and bottom axes for a plot. Assumes that the index is horizontal and value is vertical by default; set orientation to something other than "normal" if they are flipped. """ if orientation in ("normal", "h"): v_mapper = plot.value_mapper h_mapper = plot.index_mapper else: v_mapper = plot.index_mapper h_mapper = plot.value_mapper yticks = ScalesTickGenerator() left = PlotAxis( orientation='left', title=vtitle, mapper=v_mapper, component=plot, tick_generator=yticks, ) xticks = ScalesTickGenerator() bottom = PlotAxis( orientation='bottom', title=htitle, mapper=h_mapper, component=plot, tick_generator=xticks, ) plot.underlays.append(left) plot.underlays.append(bottom) return left, bottom
def _init_components(self): # Since this is called after the HasTraits constructor, we have to make # sure that we don't blow away any components that the caller may have # already set. if self.range2d is None: self.range2d = DataRange2D() if self.index_mapper is None: if self.index_scale == "linear": imap = LinearMapper(range=self.range2d.x_range) else: imap = LogMapper(range=self.range2d.x_range) self.index_mapper = imap if self.value_mapper is None: if self.value_scale == "linear": vmap = LinearMapper(range=self.range2d.y_range) else: vmap = LogMapper(range=self.range2d.y_range) self.value_mapper = vmap if self.x_ticks is None: self.x_ticks = ScalesTickGenerator( scale=self._make_scale(self.index_scale)) if self.y_ticks is None: self.y_ticks = ScalesTickGenerator( scale=self._make_scale(self.value_scale)) if self.x_grid is None: self.x_grid = PlotGrid(mapper=self.x_mapper, orientation="vertical", line_color="lightgray", line_style="dot", component=self, tick_generator=self.x_ticks) if self.y_grid is None: self.y_grid = PlotGrid(mapper=self.y_mapper, orientation="horizontal", line_color="lightgray", line_style="dot", component=self, tick_generator=self.y_ticks) if self.x_axis is None: self.x_axis = PlotAxis(mapper=self.x_mapper, orientation="bottom", component=self, tick_generator=self.x_ticks) if self.y_axis is None: self.y_axis = PlotAxis(mapper=self.y_mapper, orientation="left", component=self, tick_generator=self.y_ticks)
def _plot_series(self, po, pid, omits): graph = self.graph try: ys = [ai.nominal_value for ai in self._unpack_attr(po.name)] yerr = [ai.std_dev for ai in self._unpack_attr(po.name)] n = [ai.record_id for ai in self.sorted_analyses] args = graph.new_series(x=self.xs, y=ys, display_index=ArrayDataSource(data=n), yerror=yerr, fit=po.fit, plotid=pid, type='scatter') if len(args) == 2: scatter, p = args else: p, scatter, l = args sel = scatter.index.metadata.get('selections', []) sel += omits scatter.index.metadata['selections'] = list(set(sel)) if po.use_time_axis: p.x_axis.tick_generator = ScalesTickGenerator( scale=CalendarScaleSystem()) #p.value_scale = po.scale self._add_error_bars(scatter, yerr, 'y', 1, visible=po.y_error) except (KeyError, ZeroDivisionError), e: print 'Series', e
def make_plot(self): # ============================== #self.pd = ArrayPlotData(P_data=self.data.m_Pressures_array) # we store the array plotdata in the data object and update it there self.p_obj.values_array_pd = ArrayPlotData( P_data=self.p_obj.values_array) self.plot_ren = Plot(self.p_obj.values_array_pd) self.plot_ren.padding_left = 70 #80 self.plot_ren.padding_right = 5 self.plot_ren.padding_top = 5 self.plot_ren.padding_bottom = 40 self.plot_ren.x_axis.title = self.p_obj.x_axis self.plot_ren.y_axis.visible = False self.plot_ren.plot(("P_data"), type="line", color="blue", render_style='connectedhold') tick_gen = ScalesTickGenerator(scale=DefaultScale()) y_axis = PlotAxis(orientation='left', title=self.p_obj.y_axis, mapper=self.plot_ren.value_mapper, component=self.plot_ren, tick_generator=tick_gen) self.plot_ren.underlays.append(y_axis)
def set_time_xaxis(self, plotid=None): if plotid is None: plotid = len(self.plots) - 1 p = self.plots[plotid] p.x_axis.tick_generator = ScalesTickGenerator( scale=CalendarScaleSystem())
def _ts_data_changed(self): """ Dataset has changed: update the plot. ENH: add the possibility to pass a dict to ArrayPlotData. """ print "data changed: updating the plot..." arr_data = ArrayPlotData() for k, v in self.ts_data.items(): arr_data.set_data(k, v) self.ts_plot = ToolbarPlot(arr_data) for i, k in enumerate([k for k in self.ts_data.keys() if k != "index"]): self.ts_plot.plot(("index", k), name=k, color=colors[i % len(colors)]) if self.index_is_dates: # Index was an array of datetime: overwrite the x axis self.ts_plot.x_axis = None x_axis = PlotAxis(self.ts_plot, orientation="bottom", tick_generator=ScalesTickGenerator( scale=CalendarScaleSystem())) self.ts_plot.overlays.append(x_axis) self.ts_plot.x_grid.tick_generator = x_axis.tick_generator if self.data_file: self.ts_plot.title = "Time series visualization from %s" % self.data_file else: self.ts_plot.title = "Time series visualization" attach_tools(self.ts_plot)
def update_main_plot(self): """ Build main plot """ self.ts_plot = ToolbarPlot(self.arr_plot_data) for i, k in enumerate([k for k in self.ts_data.keys() if k != "index"]): renderer = self.ts_plot.plot(("index", k), name = k, color = colors[i % len(colors)])[0] if self.index_is_dates: # Index was an array of datetime: overwrite the x axis self.ts_plot.x_axis = None x_axis = PlotAxis(self.ts_plot, orientation="bottom", tick_generator=ScalesTickGenerator(scale=CalendarScaleSystem())) self.ts_plot.overlays.append(x_axis) self.ts_plot.x_grid.tick_generator = x_axis.tick_generator if self.data_file: self.ts_plot.title = ("Time series visualization from %s" % (os.path.split(self.data_file)[1])) else: self.ts_plot.title = "Time series visualization" attach_tools(self.ts_plot) # Attach the range selection to the last renderer; any one will do self.ts_plot.tools.append(RangeSelection(renderer, left_button_selects = False, auto_handle_event = False)) # Attach the corresponding overlay self._range_selection_overlay = RangeSelectionOverlay(renderer, metadata_name="selections") self.ts_plot.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)
def add_default_grids(plot, orientation="normal", tick_gen=None): """ Creates horizontal and vertical gridlines for a plot. Assumes that the index is horizontal and value is vertical by default; set orientation to something other than "normal" if they are flipped. """ if orientation in ("normal", "h"): v_mapper = plot.index_mapper h_mapper = plot.value_mapper else: v_mapper = plot.value_mapper h_mapper = plot.index_mapper vgrid = PlotGrid( mapper=v_mapper, orientation='vertical', component=plot, line_color="lightgray", line_style="dot", tick_generator=tick_gen) hgrid = PlotGrid( mapper=h_mapper, orientation='horizontal', component=plot, line_color="lightgray", line_style="dot", tick_generator=ScalesTickGenerator()) plot.underlays.append(vgrid) plot.underlays.append(hgrid) return hgrid, vgrid
def _create_probability_axis(self, plot): """Create plot axis for probability values.""" prob_axis = LabelAxis(plot, orientation='left', positions=[0.5, 0.5 + np.sqrt(0.25) / 2., 1.0], labels=['0', '0.25', '1']) prob_axis.tick_generator = ScalesTickGenerator(scale=FixedScale(0.001)) return prob_axis
def _plot_default(self): plot = Plot(self.dataset) plot.plot(('dates', self.data_provider.code), type='line') # Set the plot's bottom axis to use the Scales ticking system ticker = ScalesTickGenerator(scale=CalendarScaleSystem()) plot.x_axis.tick_generator = ticker return plot
def setup(self, x, y, ans): from pychron.pipeline.plot.plotter.ticks import tick_formatter, StaticTickGenerator, TICKS p = self.new_plot() p.padding_left = 60 p.y_axis.tick_label_formatter = tick_formatter p.y_axis.tick_generator = StaticTickGenerator() p.y_axis.title = 'Analysis Type' # p.y_grid.line_style='solid' # p.y_grid.line_color='green' # p.y_grid.line_weight = 1.5 self.set_y_limits(min_=-1, max_=len(TICKS)) p.index_range.tight_bounds = False p.x_axis.tick_generator = ScalesTickGenerator( scale=CalendarScaleSystem()) p.x_grid.tick_generator = p.x_axis.tick_generator p.x_axis.title = 'Time' scatter, _ = self.new_series(x, y, type='scatter', marker_size=1.5, selection_color='red', selection_marker='circle', selection_marker_size=2.5) broadcaster = BroadcasterTool() scatter.tools.append(broadcaster) point_inspector = AnalysisPointInspector( scatter, analyses=ans, value_format=get_analysis_type, additional_info=lambda i, x, y, ai: ('Time={}'.format(ai.rundate), 'Project={}'.format(ai.project))) pinspector_overlay = PointInspectorOverlay(component=scatter, tool=point_inspector) rect_tool = RectSelectionTool(scatter) rect_overlay = RectSelectionOverlay(component=scatter, tool=rect_tool) broadcaster.tools.append(rect_tool) broadcaster.tools.append(point_inspector) # range_selector = RangeSelection(scatter, left_button_selects=True) # broadcaster.tools.append(range_selector) # scatter.overlays.append(RangeSelectionOverlay(component=scatter)) scatter.overlays.append(pinspector_overlay) scatter.overlays.append(rect_overlay) self.scatter = scatter
def _set_bottom_axis(self, plota, plot, plotid, timescale=False): # this is a hack to hide the default plotaxis # since a basexyplot's axis cannot be a ScalesPlotAxis (must be instance of PlotAxis) # we cant remove the default axis and set the x_axis to the scaled axis # also we cant remove the default axis because then we cant change the axis title title, title_font, tick_font = self._remove_bottom(plot) bottom = self.plotcontainer.stack_order == 'bottom_to_top' if bottom: if plotid == 0 or timescale: axis = ScalesPlotAxis( plota, orientation="bottom", title=title, title_font=title_font, tick_label_font=tick_font, tick_generator=ScalesTickGenerator( scale=CalendarScaleSystem( # *HMSScales ) # scale = TimeScale() )) plot.underlays.append(axis) else: for pi in self.plots: title = self._remove_bottom(pi) if (plotid == 0 and len(self.plots) == 1) or plotid == len(self.plots) - 1: axis = ScalesPlotAxis( plota, orientation="bottom", title=title, title_font=title_font, tick_label_font=tick_font, tick_generator=ScalesTickGenerator( scale=CalendarScaleSystem( # *HMSScales ) # scale = TimeScale() )) plot.underlays.append(axis)
def set_time_xaxis(self, plotid=None): from chaco.scales_tick_generator import ScalesTickGenerator from chaco.scales.time_scale import CalendarScaleSystem if plotid is None: plotid = len(self.plots) - 1 p = self.plots[plotid] p.x_axis.tick_generator = ScalesTickGenerator( scale=CalendarScaleSystem())
def _figure_drift_default(self): plot = Plot(self.plot_data_drift, width=70, height=40, padding=8, padding_left=64, padding_bottom=32) plot.plot(('t','x'), type='line', color='blue', name='x') plot.plot(('t','y'), type='line', color='red', name='y') plot.plot(('t','z'), type='line', color='green', name='z') bottom_axis = PlotAxis(plot, orientation="bottom", tick_generator=ScalesTickGenerator(scale=CalendarScaleSystem())) plot.index_axis=bottom_axis plot.index_axis.title = 'time' plot.value_axis.title = 'drift [um]' plot.legend.visible=True return plot
def _plot_default(self): code = self.data_provider.code plot = Plot(self.dataset) plot.plot(('dates', code), type='line', color='blue', name=code) # Add tools plot.tools.append(ZoomTool(plot)) plot.tools.append(PanTool(plot)) # Set the plot's bottom axis to use the Scales ticking system ticker = ScalesTickGenerator(scale=CalendarScaleSystem()) plot.x_axis.tick_generator = ticker return plot
def _plot_series(self, po, pid, xs, ys): graph = self.graph try: scatter, p = graph.new_series(x=xs, y=ys, fit=po.fit, plotid=pid, type='scatter') if po.use_time_axis: p.x_axis.tick_generator = ScalesTickGenerator( scale=CalendarScaleSystem()) except (KeyError, ZeroDivisionError), e: print 'Series', e
def _plot_series(self, po, pid, omits): graph = self.graph try: if po.name == 'AnalysisType': ys = list(self._unpack_attr(po.name)) kw = dict(y=ys, colors=ys, type='cmap_scatter', marker_size=4, color_map_name='gist_rainbow') yerr = None value_format = analysis_type_formatter set_ylimits = False else: value_format = None ys = array([ai.nominal_value for ai in self._unpack_attr(po.name)]) yerr = array([ai.std_dev for ai in self._unpack_attr(po.name)]) kw = dict(y=ys, yerror=yerr, type='scatter') set_ylimits = True n = [ai.record_id for ai in self.sorted_analyses] args = graph.new_series(x=self.xs, display_index=ArrayDataSource(data=n), fit=po.fit, plotid=pid, # type='scatter', add_inspector=False, **kw) if len(args) == 2: scatter, p = args else: p, scatter, l = args sel = scatter.index.metadata.get('selections', []) sel += omits scatter.index.metadata['selections'] = list(set(sel)) self._add_scatter_inspector(scatter, value_format=value_format) if po.use_time_axis: p.x_axis.tick_generator = ScalesTickGenerator(scale=CalendarScaleSystem()) #p.value_scale = po.scale end_caps = True if po.y_error and yerr is not None: self._add_error_bars(scatter, yerr, 'y', 2, end_caps, visible=True) if set_ylimits: mi, mx = min(ys - 2 * yerr), max(ys + 2 * yerr) graph.set_y_limits(min_=mi, max_=mx, pad='0.1', plotid=pid) except (KeyError, ZeroDivisionError, AttributeError), e: print 'Series', e
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", restrict_to_data=True)) plot.overlays.append( ZoomTool(plot, tool_mode="range", max_zoom_out=1.0, x_min_zoom_factor=float(1e-3))) # 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 _container_default(self): plot = Plot(self.dataset) plot.plot(('dates', self.data_provider.code), type='line') # Add tools plot.tools.append(ZoomTool(plot)) plot.tools.append(PanTool(plot)) # Set the plot's bottom axis to use the Scales ticking system ticker = ScalesTickGenerator(scale=CalendarScaleSystem()) plot.x_axis.tick_generator = ticker container = VPlotContainer() container.add(plot) return container
def _create_returns_plot(self): plot = Plot(self.plotdata) plot.legend.visible = False 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="auto", line_width=2)[0] self.times_ds = renderer.index print('chaco: %s') % str(time.time() - tic) # 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 _create_window(self): # Create the data and datasource objects # In order for the date axis to work, the index data points need to # be in units of seconds since the epoch. This is because we are using # the CalendarScaleSystem, whose formatters interpret the numerical values # as seconds since the epoch. numpoints = 500 index = create_dates(numpoints) returns = random.lognormal(0.01, 0.1, size=numpoints) price = 100.0 * cumprod(returns) volume = abs(random.normal(1000.0, 1500.0, size=numpoints) + 2000.0) time_ds = ArrayDataSource(index) vol_ds = ArrayDataSource(volume, sort_order="none") price_ds = ArrayDataSource(price, sort_order="none") # Create the price plots price_plot, mini_plot = self._create_price_plots(time_ds, price_ds) price_plot.index_mapper.domain_limits = (index[0], index[-1]) self.price_plot = price_plot self.mini_plot = mini_plot # Create the volume plot vol_plot = self._create_vol_plot(time_ds, vol_ds) vol_plot.index_mapper.domain_limits = (index[0], index[-1]) # Set the plot's bottom axis to use the Scales ticking system ticker = ScalesTickGenerator(scale=CalendarScaleSystem()) for plot in price_plot, mini_plot, vol_plot: bottom_axis = PlotAxis(plot, orientation="bottom", tick_generator=ticker) plot.overlays.append(bottom_axis) plot.overlays.append(PlotAxis(plot, orientation="left")) hgrid, vgrid = add_default_grids(plot) vgrid.tick_generator = bottom_axis.tick_generator container = VPlotContainer(bgcolor="lightgray", spacing=40, padding=50, fill_padding=False) container.add(mini_plot, vol_plot, price_plot) return Window(self, -1, component=container)
def _add_new_plot(self, new_data): code = self.data_provider.code if code in self.dataset.list_data(): create_new_plot = False else: create_new_plot = True self.dataset.set_data(code, new_data) if create_new_plot: new_plot = Plot(self.dataset) new_plot.plot(('dates', code), type='line') tick_generator = ScalesTickGenerator(scale=CalendarScaleSystem()) new_plot.x_axis.tick_generator = tick_generator self.container.add(new_plot) self.container.request_redraw()
def _rebuild_plot(self): container = self.plot value_range = DataRange1D(low=-1, high=1.) index_range = DataRange1D(self.index_ds, high='track', tracking_amount=24 * 3600 * 365) color_mapper = cmap(range=value_range) # Remove old plots container.remove(*container.components) for val, row in zip(self.value_ds, self.rows): horizon = HorizonPlot( index=self.index_ds, value=val, index_mapper=LinearMapper(range=index_range, stretch_data=False), value_mapper=BandedMapper(range=DataRange1D(val)), color_mapper=cmap(range=DataRange1D(val)), #color_mapper, negative_bands=False, ) horizon.tools.append( PanTool(horizon, constrain=True, constrain_direction="x")) horizon.overlays.append( PlotLabel(component=horizon, hjustify='right', text=row, overlay_position='outside left')) container.add(horizon) bottom_axis = PlotAxis( horizon, orientation="bottom", tick_generator=ScalesTickGenerator(scale=CalendarScaleSystem())) container.overlays = [bottom_axis] container.request_redraw()
def _add_new_plot(self, new_data): code = self.data_provider.code if code in self.dataset.list_data(): create_new_plot = False else: create_new_plot = True self.dataset.set_data(code, new_data) if create_new_plot: new_plot = Plot(self.dataset) new_plot.plot(('dates', code), type='line') new_plot.tools.append(PanTool(new_plot)) tick_generator = ScalesTickGenerator(scale=CalendarScaleSystem()) new_plot.x_axis.tick_generator = tick_generator # connect the index of the first plot with the new plot first_plot = self.container.components[0] new_plot.index_range = first_plot.index_range self.container.add(new_plot) self.container.request_redraw()
def _create_increment_one_axis(self, plot, start, number, orientation, ticks=None): """Create axis with ticks at a distance of one units. Parameters ---------- plot : Plot plot where the axis will be attached start : float position of first tick number : int number of ticks orientation: ['top', 'bottom', 'left', 'right'] position of axis on the plot ticks : list of strings string to be displayed for each tick """ ids = start + np.arange(0, number) if ticks is None: ticks = [str(idx) for idx in np.arange(0, number)] axis = LabelAxis(plot, orientation=orientation, positions=ids, labels=ticks, label_rotation=0) # use a FixedScale tick generator with a resolution of 1 axis.tick_generator = ScalesTickGenerator(scale=FixedScale(1.)) return axis
def update_main_plot(self): """ Build main plot """ self.ts_plot = ToolbarPlot(self.arr_plot_data) for i, k in enumerate([k for k in self.ts_data.keys() if k != "index"]): self.ts_plot.plot(("index", k), name=k, color=colors[i % len(colors)]) if self.index_is_dates: # Index was an array of datetime: overwrite the x axis self.ts_plot.x_axis = None x_axis = PlotAxis(self.ts_plot, orientation="bottom", tick_generator=ScalesTickGenerator( scale=CalendarScaleSystem())) self.ts_plot.overlays.append(x_axis) self.ts_plot.x_grid.tick_generator = x_axis.tick_generator if self.data_file: self.ts_plot.title = "Time series visualization from %s" % self.data_file else: self.ts_plot.title = "Time series visualization" attach_tools(self.ts_plot)
def _create_plot_components(): # Create the data and datasource objects # In order for the date axis to work, the index data points need to # be in units of seconds since the epoch. This is because we are using # the CalendarScaleSystem, whose formatters interpret the numerical values # as seconds since the epoch. high = 1. numpoints = 5000 random.seed(1000) index = create_dates(numpoints) price = 100 * cumprod(random.lognormal(0.0, 0.04, size=numpoints)) changes = price / price[0] - 1. index_ds = ArrayDataSource(index) value_ds = ArrayDataSource(changes, sort_order="none") value_range = DataRange1D(value_ds, low=-high, high=high) index_mapper = LinearMapper(range=DataRange1D(index_ds), stretch_data=False) horizon = HorizonPlot( bands=4, index=index_ds, value=value_ds, index_mapper=index_mapper, value_mapper=BandedMapper(range=DataRange1D(low=0, high=high)), color_mapper=cmap(range=value_range), ) horizon.tools.append( PanTool(horizon, constrain=True, constrain_direction="x")) axis = PlotAxis(mapper=horizon.value_mapper, component=horizon, orientation="left", tick_label_position="outside") horizon.overlays.append(axis) bottom_axis = PlotAxis( horizon, orientation="bottom", tick_generator=ScalesTickGenerator(scale=CalendarScaleSystem())) horizon.overlays.append(bottom_axis) filled = FilledLinePlot( index=index_ds, value=value_ds, index_mapper=index_mapper, value_mapper=LinearMapper(range=value_range, stretch_data=False), fill_color=(0.81960784, 0.89803922, 0.94117647), edge_color='transparent', ) filled.tools.append( PanTool(filled, constrain=True, constrain_direction="x")) axis = PlotAxis(mapper=filled.value_mapper, component=filled, orientation="left", tick_label_position="outside") filled.overlays.append(axis) grid = PlotGrid( mapper=filled.value_mapper, component=filled, orientation='horizontal', line_color='lightgray', line_style="dot", ) filled.underlays.append(grid) colormap = horizon.color_mapper colorbar = ColorBar(index_mapper=LinearMapper(range=colormap.range), color_mapper=colormap, orientation='v', resizable='v', width=20, padding=20) padding = (40, 20, 0, 0) over1 = HPlotContainer(use_backbuffer=True, padding=padding, padding_top=20) over1.add(filled) over1.add(colorbar) over2 = OverlayPlotContainer(padding=padding, padding_bottom=40) over2.add(horizon) return over1, over2
def _create_plot_component(self): # find longest date index_lengths = [] for stock in self.stocks: if stock.stock_data_cache is not None: index_lengths.append(len(stock.stock_data_cache['date'])) else: index_lengths.append(len(stock.stock_data['date'])) index_lengths = np.array(index_lengths) lngest = index_lengths.argmax() shrtest = index_lengths.argmin() index = np.array([ time.mktime(x.timetuple()) for x in self.stocks[lngest].dates.tolist() ]) sel_range_low = time.mktime( self.stocks[shrtest].dates.tolist()[0].timetuple()) sel_range_high = time.mktime( self.stocks[shrtest].dates.tolist()[-1].timetuple()) sel_range_low_idx = np.where(index == sel_range_low)[0].item() sel_range_high_idx = np.where(index == sel_range_high)[0].item() pd = ArrayPlotData() # Now plot the returns for each asset (cumulative sum of periodic rates of return) for i in range(len(self.stocks)): if self.stocks[i].stock_data_cache is None: stk = self.stocks[i].stock_data else: stk = self.stocks[i].stock_data_cache pd.set_data( "idx%s" % i, np.array([ time.mktime(x.timetuple()) for x in stk['date'].tolist() ])) pd.set_data("y%s" % i, metrics.rate_array(stk)['rate'].cumsum()) plot = Plot(pd, bgcolor="none", padding=30, border_visible=True, overlay_border=True, use_backbuffer=False) for i in range(len(self.stocks)): # hang on to a reference to the last one of these... plt = plot.plot(("idx%s" % i, "y%s" % i), name=self.stocks[i].symbol, color=self.colors[i]) #value_range = plot.value_mapper.range #index_range = plot.index_mapper.range plt[0].active_tool = RangeSelection(plt[0], left_button_selects=True) plt[0].active_tool.selection = [ index[sel_range_low_idx], index[sel_range_high_idx] ] plt[0].overlays.append(RangeSelectionOverlay(component=plt[0])) #plot.bgcolor = "white" plot.padding = 50 add_default_grids(plot) # Set the plot's bottom axis to use the Scales ticking system scale_sys = CalendarScaleSystem( fill_ratio=0.4, default_numlabels=5, default_numticks=10, ) tick_gen = ScalesTickGenerator(scale=scale_sys) bottom_axis = PlotAxis(plot, orientation="bottom", tick_generator=tick_gen, label_color="white", line_color="white") # Hack to remove default axis - TODO: how do I *replace* an axis? del (plot.underlays[-4]) plot.overlays.append(bottom_axis) plot.legend.visible = True return plot
def setup(self, x, y, ans, atypes, mapping): from pychron.pipeline.plot.plotter.ticks import StaticTickGenerator def get_analysis_type(x): x = int(math.floor(x)) return next((k for k, v in mapping.items() if v == x)) p = self.new_plot() p.padding_left = 200 def tickformatter(x): return atypes[int(x)] p.y_axis.tick_label_rotate_angle = 60 p.y_axis.tick_label_formatter = tickformatter p.y_axis.tick_generator = StaticTickGenerator(_nticks=len(atypes)) p.y_axis.title = 'Analysis Type' p.y_axis.title_font = 'modern 18' p.y_axis.tick_label_font = 'modern 14' self.add_axis_tool(p, p.x_axis) self.add_axis_tool(p, p.y_axis) self.add_limit_tool(p, 'x') self.add_limit_tool(p, 'y') self.set_y_limits(min_=-1, max_=len(atypes)) p.index_range.tight_bounds = False p.x_axis.tick_generator = ScalesTickGenerator( scale=CalendarScaleSystem()) p.x_grid.tick_generator = p.x_axis.tick_generator p.x_axis.title = 'Time' p.x_axis.title_font = 'modern 18' p.x_axis.tick_label_font = 'modern 14' t = GroupingTool(component=p) p.tools.append(t) o = GroupingOverlay(component=p, tool=t) p.overlays.append(o) self.grouping_tool = t scatter, _ = self.new_series(x, y, type='scatter', marker_size=1.5, selection_color='red', selection_marker='circle', selection_marker_size=2.5) broadcaster = BroadcasterTool() scatter.tools.append(broadcaster) point_inspector = AnalysisPointInspector( scatter, analyses=ans, value_format=get_analysis_type, additional_info=lambda i, x, y, ai: ('Time={}'.format(ai.rundate), 'Project={}'.format(ai.project))) pinspector_overlay = PointInspectorOverlay(component=scatter, tool=point_inspector) rect_tool = RectSelectionTool(scatter) rect_overlay = RectSelectionOverlay(component=scatter, tool=rect_tool) broadcaster.tools.append(rect_tool) broadcaster.tools.append(point_inspector) scatter.overlays.append(pinspector_overlay) scatter.overlays.append(rect_overlay) self.scatter = scatter
def _create_plot_component(): container = OverlayPlotContainer( padding=50, fill_padding=True, bgcolor="lightgray", use_backbuffer=True) # Create the initial X-series of data numpoints = 100 low = -5 high = 15.0 x = linspace(low, high, numpoints) now = time() timex = linspace(now, now + 7 * 24 * 3600, numpoints) # Plot some bessel functions value_mapper = None index_mapper = None plots = {} for i in range(10): y = jn(i, x) if i % 2 == 1: plot = create_line_plot( (timex, y), color=tuple(COLOR_PALETTE[i]), width=2.0) plot.index.sort_order = "ascending" else: plot = create_scatter_plot( (timex, y), color=tuple(COLOR_PALETTE[i])) plot.bgcolor = "white" plot.border_visible = True if i == 0: value_mapper = plot.value_mapper index_mapper = plot.index_mapper left, bottom = add_default_axes(plot) left.tick_generator = ScalesTickGenerator() bottom.tick_generator = ScalesTickGenerator( scale=CalendarScaleSystem()) add_default_grids(plot, tick_gen=bottom.tick_generator) else: plot.value_mapper = value_mapper value_mapper.range.add(plot.value) plot.index_mapper = index_mapper index_mapper.range.add(plot.index) if i == 0: plot.tools.append(PanTool(plot)) zoom = ZoomTool(plot, tool_mode="box", always_on=False) plot.overlays.append(zoom) # Add a legend in the upper right corner, and make it relocatable legend = Legend(component=plot, padding=10, align="ur") legend.tools.append(LegendTool(legend, drag_button="right")) plot.overlays.append(legend) container.add(plot) plots["Bessel j_%d" % i] = plot # Set the list of plots on the legend legend.plots = plots # Add the title at the top container.overlays.append( PlotLabel( "Bessel functions", component=container, font="swiss 16", overlay_position="top")) # Add the traits inspector tool to the container container.tools.append(TraitsTool(container)) return container