python - Add point in interactive plot Chaco -
i'm using chaco , traits.api interactive plot. can select points in plot, , calculus. need update initial plot, don't know how (i need add points). thanks
this code
import numpy np enable.component_editor import componenteditor traits.api import hastraits, instance, int, list, str, enum, on_trait_change, any, delegatesto, array traitsui.api import item, view, hsplit, vgroup, enumeditor, hgroup, spring, label enthought.traits.api import hastraits, array, range, float, enum, on_trait_change, property chaco.api import arrayplotdata, plot, plotaxis, \ scatterinspectoroverlay chaco.chaco_plot_editor import chacoplotitem chaco.scales.api import calendarscalesystem chaco.scales_tick_generator import scalestickgenerator chaco.example_support import color_palette chaco.tools.api import pantool, zoomtool, rangeselection, \ rangeselectionoverlay, legendtool, scatterinspector # attributes use plot view. size=(800,800) title="scatter plot selection" bg_color="lightgray" #=============================================================================== class plotapp(hastraits): plotdata = instance(arrayplotdata) returns_plot = instance(plot) plot_type = enum('line', 'scatter') corr_renderer = any() x_min = float() x_max = float() posicion_puntos_selec = array traits_view = view( vgroup( hgroup(spring, label('click point select/unselect'), spring), #item('plot_type'), item('returns_plot', editor=componenteditor(size=size, bgcolor=bg_color), show_label=false), orientation = "vertical"), resizable=true, title=title ) def __init__(self, *symbols, **kwtraits): super(plotapp, self).__init__(symbols=list(symbols), **kwtraits) self._create_data() self._create_returns_plot() return def _create_returns_plot(self): plot = plot(self.plotdata) plot.legend.visible = true plot.x_axis = none x_axis = plotaxis(plot, orientation="bottom") plot.overlays.append(x_axis) renderer = plot.plot(("index", "value"), type="scatter")[0] #agrego todas las tools necesarias renderer.tools.append(scatterinspector(renderer, selection_mode="toggle", persistent_hover=false)) renderer.overlays.append( scatterinspectoroverlay(renderer, hover_color = "transparent", hover_marker_size = 10, hover_outline_color = "purple", hover_line_width = 2, selection_marker_size = 8, selection_color = "red") ) renderer.tools.append(rangeselection(renderer, left_button_selects = false, disable_left_mouse = true, \ rigth_button_selects = true, \ auto_handle_event = false, metadata_name = "annotations")) renderer.overlays.append(rangeselectionoverlay(component=renderer, metadata_name = "annotations")) renderer.tools.append(pantool(renderer)) renderer.overlays.append(zoomtool(renderer, drag_button="right")) self.index_datasource = renderer.index self.index_datasource.on_trait_change(self._selections_changed, "metadata_changed") self.returns_plot = plot def _create_data(self): #genero los datos, más adelante los voy leer con pandas npts = 40 x_max = 10 x = np.random.random(npts) x = x * x_max error = np.random.random(npts) y = 2 + 3*x + 5*error #esta parte es para ordenar los elementos x_ordenado = np.array([]) y_ordenado = np.array([]) orden = range(x.size) nuevo_orden = np.array([]) in range(x.size): arg_min = x.argmin() x_ordenado = np.append(x_ordenado, x[arg_min]) y_ordenado = np.append(y_ordenado, y[arg_min]) nuevo_orden = np.append(nuevo_orden, orden[arg_min]) x = np.delete(x, arg_min) y = np.delete(y, arg_min) orden = np.delete(orden, arg_min) self.x_ordenado = x_ordenado self.y_ordenado = y_ordenado #genero el retorno para el plot plotdata = arrayplotdata() plotdata.set_data("index", x_ordenado) plotdata.set_data("value", y_ordenado) self.plotdata = plotdata def _selections_changed(self): #obtengo los puntos marcados manualmente seleccionado_manu = self.index_datasource.metadata.get('selections', ()) #obtengo los puntos que marque con el rectangulo seleccionado_range = self.index_datasource.metadata.get('annotations', ()) #cuando desmarcon con el rectangu, el tipo de annotations es nonetype, #con este if lo cambio tuple type_range = type(self.index_datasource.metadata['annotations']) if type_range != tuple: self.index_datasource.metadata['annotations'] = [] else: self.x_min, self.x_max = seleccionado_range self.posicion_puntos_selec = seleccionado_manu def calculos(self): indice_min = 0 x_selec = np.delete(self.x_ordenado, self.posicion_puntos_selec) y_selec = np.delete(self.y_ordenado, self.posicion_puntos_selec) indice_max = x_selec.size - 1 #ara saber los extremos del vector x que son tomado por rangesel if self.x_min != 0 , self.x_max != 0: while self.x_min >= x_selec[indice_min]: indice_min += 1 while self.x_max <= x_selec[indice_max]: indice_max -= 1 #x e y con los cuales quiero hacer los calculos self.x_calcular = x_selec[indice_min:indice_max + 1] self.y_calcular = y_selec[indice_min:indice_max + 1] @on_trait_change("x_min, x_max, posicion_puntos_selec") def _perform_calculations(self): self.calculos() plot = plot(self.plotdata) renderer = plot.plot(("index", "value"), type="scatter")[0] demo = plotapp("aapl", "goog", "msft") if __name__ == "__main__": demo.configure_traits()
take @ chaco example data_stream.py. data in example updated every 100ms in response timer tick (the callback function timer_tick()
in controller
class) https://github.com/enthought/chaco/blob/master/examples/demo/advanced/data_stream.py
Comments
Post a Comment