enthought / enthought/chaco

Clean up and add PlotSelectionTool

Open
#464 1 comment 0 reactions 0 assignees View on GitHub
type: enhancement
Dominant language
Python
Stars
305
Forks
97
PR merge metrics
No merged PRs in 30d

Description

Some prototype code and example originally written by @corranwebster:

```python
import numpy as np

from chaco.api import ArrayPlotData, Plot
from chaco.tools.api import SelectTool
from enable.api import ComponentEditor
from traits.api import Any, HasTraits, Instance, Int, List, Set, Str, Tuple, on_trait_change
from traitsui.api import CheckListEditor, UItem, View

class PlotSelectionTool(SelectTool):

selection = Set(Tuple(Str, Int))

def _get_selection_state(self, event):
token = self._get_selection_token(event)
if token is not None:
return (token in self.selection, True)
else:
return (False, False)

def _get_selection_token(self, event):
plot = self.component
event.offset_xy(self.component.x, self.component.y)
try:
for name, renderers in plot.plots.items():
for index, renderer in enumerate(renderers):
if hasattr(renderer, "hittest"):
target = renderer.hittest(
(event.x, event.y),
self.threshold,
)
if target is not None:
return (name, index)
return None
finally:
event.pop()

def _select(self, token, append=True):
""" Selects the given token.
"""
if append:
self.selection.add(token)
else:
self.selection = {token}

def _deselect(self, token, append=True):
""" Deselects the given token.
"""
if append:
self.selection.discard(token)
else:
self.selection = {}

class SelectablePlots(HasTraits):

plot = Instance(Plot)

selection_tool = Instance(PlotSelectionTool)

selected_renderers = List(Str)

selectable_renderers = List(Str)

@on_trait_change('selection_tool:selection[]', post_init=True)
def _on_selection(self):
if self.plot is None:
return

self.selected_renderers = [
name for name, index in self.selection_tool.selection
]

def _selected_renderers_changed(self):
if self.plot is None:
return

unselected_renderers = {
name for name in self.plot.plots
if name not in self.selected_renderers
}
for name in self.selected_renderers:
renderer = self.plot.plots[name][0]
renderer.line_width = 3.0
renderer.alpha = 1.0

for name in unselected_renderers:
renderer = self.plot.plots[name][0]
renderer.line_width = 1.0
if self.selected_renderers:
renderer.alpha = 0.5
else:
renderer.alpha = 1.0

def _plot_default(self):
data = np.random.standard_normal((10, 1000))
data = data.cumsum(axis=-1)

plot_data = ArrayPlotData()
for i, row in enumerate(data):
plot_data.set_data('y{}'.format(i), row)
plot_data.set_data('x{}'.format(i), np.linspace(0, 100, 1000))

plot = Plot(plot_data)

for i in range(len(data)):
renderer = plot.plot(
('x{}'.format(i), 'y{}'.format(i)),
name="random walk {}".format(i),
color='auto',
)[0]
renderer.index.sort_order='ascending'

self.selection_tool = PlotSelectionTool(
component=plot,
selection={(name, 0) for name in self.selected_renderers}
)
plot.tools.append(self.selection_tool)

return plot

def _selectable_renderers_default(self):
return ["random walk {}".format(i) for i in range(10)]

trait_view = View(
UItem('plot', editor=ComponentEditor()),
UItem(
'selected_renderers',
editor=CheckListEditor(
name='selectable_renderers',
cols=2,
),
style='custom',
),
resizable=True,
)

if __name__ == '__main__':
p = SelectablePlots()
p.configure_traits()

```

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.