3
from enthought.traits.api import Instance, HasTraits, Range, Array
4
from enthought.traits.ui.api import View, Item, HGroup, VGroup, Group
6
from enthought.enable.api import ComponentEditor
8
from enthought.chaco.api import LinearMapper, Plot, ArrayDataSource, DataRange1D, PlotAxis
9
from enthought.chaco.multi_array_data_source import MultiArrayDataSource
10
from enthought.chaco.multi_line_plot import MultiLinePlot
13
class DataModel(HasTraits):
14
"""This is the data to be plotted in the demo."""
16
# The x values of the data (1D numpy array).
19
# The channel numbers (1D numpy array).
22
# The data. The shape of this 2D array must be (y_index.size, x_index.size)
26
class MultiLinePlotDemo(HasTraits):
27
"""Demonstrates the MultiLinePlot.
29
This demo assumes that 'model', an instance of DataModel containing the 2D
30
data to be plotted, will be given to the constructor, and will not change
34
model = Instance(DataModel)
38
multi_line_plot_renderer = Instance(MultiLinePlot)
40
# Drives multi_line_plot_renderer.normalized_amplitude
41
amplitude = Range(-1.5, 1.5, value=-0.5)
43
# Drives multi_line_plot_renderer.offset
44
offset = Range(-1.0, 1.0, value=0)
50
Item('plot', editor=ComponentEditor(), show_label=False),
53
Item('amplitude', springy=True),
54
Item('offset', springy=True),
58
Item('object.multi_line_plot_renderer.color', springy=True),
59
Item('object.multi_line_plot_renderer.line_style', springy=True),
69
#-----------------------------------------------------------------------
71
#-----------------------------------------------------------------------
73
def _multi_line_plot_renderer_default(self):
74
"""Create the default MultiLinePlot instance."""
76
xs = ArrayDataSource(self.model.x_index, sort_order='ascending')
77
xrange = DataRange1D()
80
ys = ArrayDataSource(self.model.y_index, sort_order='ascending')
81
yrange = DataRange1D()
84
# The data source for the MultiLinePlot.
85
ds = MultiArrayDataSource(data=self.model.data)
87
multi_line_plot_renderer = \
91
index_mapper = LinearMapper(range=xrange),
92
value_mapper = LinearMapper(range=yrange),
94
global_max = self.model.data.max(),
95
global_min = self.model.data.min())
97
return multi_line_plot_renderer
99
def _plot_default(self):
100
"""Create the Plot instance."""
102
plot = Plot(title="MultiLinePlot Demo")
103
plot.add(self.multi_line_plot_renderer)
105
x_axis = PlotAxis(component=plot,
106
mapper=self.multi_line_plot_renderer.index_mapper,
107
orientation='bottom',
109
y_axis = PlotAxis(component=plot,
110
mapper=self.multi_line_plot_renderer.value_mapper,
113
plot.overlays.extend([x_axis, y_axis])
116
#-----------------------------------------------------------------------
117
# Trait change handlers
118
#-----------------------------------------------------------------------
120
def _amplitude_changed(self, amp):
121
self.multi_line_plot_renderer.normalized_amplitude = amp
123
def _offset_changed(self, off):
124
self.multi_line_plot_renderer.offset = off
125
# FIXME: The change does not trigger a redraw. Force a redraw by
126
# faking an amplitude change.
127
self.multi_line_plot_renderer._amplitude_changed()
130
if __name__ == "__main__":
136
t = np.arange(num_samples) / fs
138
channels = np.arange(12)
139
# Frequencies of the sine functions in each channel.
140
freqs = 3*(channels[:,None] + 1)
141
y = np.sin(freqs * t)
143
# Create an instance of DataModel. This is the data to
144
# be plotted with a MultiLinePlot.
145
data = DataModel(x_index=t, y_index=channels, data=y)
147
# Create the demo class, and show it.
148
demo = MultiLinePlotDemo(model=data)
149
demo.configure_traits()