我需要在chaco的现有情节中添加一些观点。我试过了plot.request_redraw()
,但它没有用。我还能做什么?
这是一段代码:
class PlotApp(HasTraits):
plotdata = Instance(ArrayPlotData)
returns_plot = Instance(Plot)
plot_type = Enum('line', 'scatter')
corr_renderer = Any()
x_min = Float()
x_max = Float()
traits_view = View(
VGroup(
HGroup(spring, Label('Click point to select/unselect'),
spring),
#Item('plot_type'),
Item('returns_plot', editor=ComponentEditor(size=size,
bgcolor=bg_color),
show_label=False),
#Item('num_medicion', width=-225),
orientation = "vertical"),
resizable=True, title=title
)
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",name = "Mediciones")[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 a 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([])
for i 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
self.posicion_puntos_selec = 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 a 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
@on_trait_change("posicion_puntos_selec, x_min, x_max")
def _perform_calculations(self):
plot = self.returns_plot
x_nuevo = np.append(self.x_calcular, [11, 12])
y_nuevo = np.append(self.y_calcular, [11, 12])
self.corr_renderer = plot.plot((x_nuevo, y_nuevo),
type="scatter", color="blue")[0]
plot.request_redraw()
答案 0 :(得分:4)
要更新现有绘图的数据,最好也是最简单的方法是更新正在显示的现有Plot实例的现有ArrayPlotData。 Chaco内部的听众将负责重绘。以下是一个受您的代码启发的示例:
from traits.api import HasTraits, Enum, Instance, Button
from traitsui.api import View, Item, VGroup
from enable.api import ComponentEditor
from chaco.api import Plot, ArrayPlotData, PlotAxis
from numpy import arange
class PlotApp(HasTraits):
plotdata = Instance(ArrayPlotData)
returns_plot = Instance(Plot)
plot_type = Enum('line', 'scatter')
add_points = Button
traits_view = View(
VGroup(Item("add_points"),
Item('returns_plot', editor=ComponentEditor(),
show_label=False),
orientation = "vertical"),
resizable=True, title="Test"
)
def _returns_plot_default(self):
self.plotdata = ArrayPlotData(index=arange(100), value=arange(100))
plot = Plot(self.plotdata)
plot.legend.visible = True
plot.x_axis = None
x_axis = PlotAxis(plot, orientation="bottom")
plot.overlays.append(x_axis)
plot.plot(("index", "value"), type="scatter", name = "Mediciones")
return plot
def _add_points_fired(self):
current_length = len(self.plotdata["index"])
self.plotdata.set_data("index", arange(current_length+1))
self.plotdata.set_data("value", arange(current_length+1))
if __name__ == "__main__":
app = PlotApp()
app.configure_traits()
HTH, 乔纳森