Created
July 25, 2019 16:47
-
-
Save scott-maddox/2f1103b474c9dcb1a539c65b6d6d8cd6 to your computer and use it in GitHub Desktop.
chaco line plots with line labels on hover
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from numpy import array, inf, linspace | |
from scipy.special import jn | |
from chaco.api import ArrayDataSource, ArrayPlotData, DataLabel, Plot | |
from chaco.tools.api import SimpleInspectorTool | |
from enable.api import BaseTool, ComponentEditor | |
from traits.api import HasTraits, Instance, on_trait_change | |
from traitsui.api import Item, View | |
class HoverLinePlots(HasTraits): | |
inspector = Instance(SimpleInspectorTool) | |
label = Instance(DataLabel) | |
plot = Instance(Plot) | |
@on_trait_change('inspector:new_value') | |
def handle_inspection(self, value): | |
point = self.inspector.last_mouse_position | |
if point: | |
# run through all the plots in the Plot and find closest within threshhold | |
best = None | |
best_distance = inf | |
# inspector is attached to Plot, so we need to adjust screen coords | |
# to take into account padding | |
adjusted_point = ( | |
point[0] - self.plot.padding[0], | |
point[1] - self.plot.padding[1] | |
) | |
for name, plots in self.plot.plots.items(): | |
for renderer in plots: | |
result = renderer.hittest(adjusted_point, return_distance=True) | |
if result is not None and result[-1] < best_distance: | |
best = name | |
best_distance = result[-1] | |
# adjust label text and position (or hide if nothing) | |
if best is not None: | |
self.label.label_text = best | |
self.label.data_point = array([value['x'], value['y']]) | |
self.label.visible = True | |
else: | |
self.label.visible = False | |
self.label.invalidate_and_redraw() | |
def __init__(self, **traits): | |
super(HoverLinePlots, self).__init__(**traits) | |
self.init() | |
def init(self): | |
""" Set up the plot inspector and label. """ | |
x = linspace(0.0, 10.0, 100) | |
data = ArrayPlotData( | |
x=ArrayDataSource(x, 'ascending'), | |
) | |
for i in range(10): | |
data.set_data('j{}'.format(i), jn(x, i)) | |
self.plot = Plot(data) | |
for i in range(10): | |
y_name = 'j{}'.format(i) | |
self.plot.plot(('x', y_name), name=y_name, color='auto') | |
self.inspector = SimpleInspectorTool(self.plot) | |
self.plot.tools.append(self.inspector) | |
self.label = DataLabel( | |
self.plot, | |
visible=False, | |
label_style='bubble', | |
corner_radius=5, | |
marker_visible=False, | |
show_label_coords=False, | |
border_width=0, | |
bgcolor=(0.5, 0.5, 0.5, 0.5), | |
) | |
self.plot.overlays.append(self.label) | |
traits_view = View( | |
Item('plot', show_label=False, editor=ComponentEditor()), | |
resizable=True, | |
) | |
if __name__ == '__main__': | |
hpl = HoverLinePlots() | |
hpl.configure_traits() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment