~ubuntu-branches/ubuntu/utopic/python-chaco/utopic

« back to all changes in this revision

Viewing changes to examples/demo/edit_line.py

  • Committer: Package Import Robot
  • Author(s): Andrew Starr-Bochicchio
  • Date: 2014-06-01 17:04:08 UTC
  • mfrom: (7.2.5 sid)
  • Revision ID: package-import@ubuntu.com-20140601170408-m86xvdjd83a4qon0
Tags: 4.4.1-1ubuntu1
* Merge from Debian unstable. Remaining Ubuntu changes:
 - Let the binary-predeb target work on the usr/lib/python* directory
   as we don't have usr/share/pyshared anymore.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
#!/usr/bin/env python
2
 
"""
3
 
Allows editing of a line plot.
4
 
 
5
 
Left-dragging a point will move its position.
6
 
 
7
 
Right-drag pans the plot.
8
 
 
9
 
Mousewheel up and down zooms the plot in and out.
10
 
 
11
 
Pressing "z" brings up the Zoom Box, and you can click-drag a rectangular region to
12
 
zoom.  If you use a sequence of zoom boxes, pressing alt-left-arrow and
13
 
alt-right-arrow moves you forwards and backwards through the "zoom history".
14
 
"""
15
 
 
16
 
# Major library imports
17
 
from numpy import linspace
18
 
from scipy.special import jn
19
 
 
20
 
from chaco.example_support import COLOR_PALETTE
21
 
 
22
 
# Enthought library imports
23
 
from enable.tools.api import DragTool
24
 
from enable.api import Component, ComponentEditor
25
 
from traits.api import HasTraits, Instance, Int, Tuple
26
 
from traitsui.api import Item, Group, View
27
 
 
28
 
# Chaco imports
29
 
from chaco.api import add_default_axes, add_default_grids, \
30
 
        OverlayPlotContainer, PlotLabel, ScatterPlot, create_line_plot
31
 
from chaco.tools.api import PanTool, ZoomTool
32
 
 
33
 
 
34
 
 
35
 
class PointDraggingTool(DragTool):
36
 
 
37
 
    component = Instance(Component)
38
 
 
39
 
    # The pixel distance from a point that the cursor is still considered
40
 
    # to be 'on' the point
41
 
    threshold = Int(5)
42
 
 
43
 
    # The index of the point being dragged
44
 
    _drag_index = Int(-1)
45
 
 
46
 
    # The original dataspace values of the index and value datasources
47
 
    # corresponding to _drag_index
48
 
    _orig_value = Tuple
49
 
 
50
 
    def is_draggable(self, x, y):
51
 
        # Check to see if (x,y) are over one of the points in self.component
52
 
        if self._lookup_point(x, y) is not None:
53
 
            return True
54
 
        else:
55
 
            return False
56
 
 
57
 
    def normal_mouse_move(self, event):
58
 
        plot = self.component
59
 
 
60
 
        ndx = plot.map_index((event.x, event.y), self.threshold)
61
 
        if ndx is None:
62
 
            if plot.index.metadata.has_key('selections'):
63
 
                del plot.index.metadata['selections']
64
 
        else:
65
 
            plot.index.metadata['selections'] = [ndx]
66
 
 
67
 
        plot.invalidate_draw()
68
 
        plot.request_redraw()
69
 
 
70
 
 
71
 
    def drag_start(self, event):
72
 
        plot = self.component
73
 
        ndx = plot.map_index((event.x, event.y), self.threshold)
74
 
        if ndx is None:
75
 
            return
76
 
        self._drag_index = ndx
77
 
        self._orig_value = (plot.index.get_data()[ndx], plot.value.get_data()[ndx])
78
 
 
79
 
    def dragging(self, event):
80
 
        plot = self.component
81
 
 
82
 
        data_x, data_y = plot.map_data((event.x, event.y))
83
 
 
84
 
        plot.index._data[self._drag_index] = data_x
85
 
        plot.value._data[self._drag_index] = data_y
86
 
        plot.index.data_changed = True
87
 
        plot.value.data_changed = True
88
 
        plot.request_redraw()
89
 
 
90
 
    def drag_cancel(self, event):
91
 
        plot = self.component
92
 
        plot.index._data[self._drag_index] = self._orig_value[0]
93
 
        plot.value._data[self._drag_index] = self._orig_value[1]
94
 
        plot.index.data_changed = True
95
 
        plot.value.data_changed = True
96
 
        plot.request_redraw()
97
 
 
98
 
    def drag_end(self, event):
99
 
        plot = self.component
100
 
        if plot.index.metadata.has_key('selections'):
101
 
            del plot.index.metadata['selections']
102
 
        plot.invalidate_draw()
103
 
        plot.request_redraw()
104
 
 
105
 
    def _lookup_point(self, x, y):
106
 
        """ Finds the point closest to a screen point if it is within self.threshold
107
 
 
108
 
        Parameters
109
 
        ==========
110
 
        x : float
111
 
            screen x-coordinate
112
 
        y : float
113
 
            screen y-coordinate
114
 
 
115
 
        Returns
116
 
        =======
117
 
        (screen_x, screen_y, distance) of datapoint nearest to the input *(x,y)*.
118
 
        If no data points are within *self.threshold* of *(x,y)*, returns None.
119
 
        """
120
 
 
121
 
        if hasattr(self.component, 'get_closest_point'):
122
 
            # This is on BaseXYPlots
123
 
            return self.component.get_closest_point((x,y), threshold=self.threshold)
124
 
 
125
 
        return None
126
 
 
127
 
 
128
 
#===============================================================================
129
 
# # Create the Chaco plot.
130
 
#===============================================================================
131
 
def _create_plot_component():
132
 
 
133
 
    container = OverlayPlotContainer(padding = 50, fill_padding = True,
134
 
                                     bgcolor = "lightgray", use_backbuffer=True)
135
 
 
136
 
    # Create the initial X-series of data
137
 
    numpoints = 30
138
 
    low = -5
139
 
    high = 15.0
140
 
    x = linspace(low, high, numpoints)
141
 
    y = jn(0, x)
142
 
 
143
 
    lineplot = create_line_plot((x,y), color=tuple(COLOR_PALETTE[0]), width=2.0)
144
 
    lineplot.selected_color = "none"
145
 
    scatter = ScatterPlot(index = lineplot.index,
146
 
                       value = lineplot.value,
147
 
                       index_mapper = lineplot.index_mapper,
148
 
                       value_mapper = lineplot.value_mapper,
149
 
                       color = tuple(COLOR_PALETTE[0]),
150
 
                       marker_size = 5)
151
 
    scatter.index.sort_order = "ascending"
152
 
 
153
 
    scatter.bgcolor = "white"
154
 
    scatter.border_visible = True
155
 
 
156
 
    add_default_grids(scatter)
157
 
    add_default_axes(scatter)
158
 
 
159
 
    scatter.tools.append(PanTool(scatter, drag_button="right"))
160
 
 
161
 
    # The ZoomTool tool is stateful and allows drawing a zoom
162
 
    # box to select a zoom region.
163
 
    zoom = ZoomTool(scatter, tool_mode="box", always_on=False, drag_button=None)
164
 
    scatter.overlays.append(zoom)
165
 
 
166
 
    scatter.tools.append(PointDraggingTool(scatter))
167
 
 
168
 
    container.add(lineplot)
169
 
    container.add(scatter)
170
 
 
171
 
    # Add the title at the top
172
 
    container.overlays.append(PlotLabel("Line Editor",
173
 
                              component=container,
174
 
                              font = "swiss 16",
175
 
                              overlay_position="top"))
176
 
 
177
 
    return container
178
 
 
179
 
 
180
 
#===============================================================================
181
 
# Attributes to use for the plot view.
182
 
size=(800,700)
183
 
title="Simple line plot"
184
 
#===============================================================================
185
 
# # Demo class that is used by the demo.py application.
186
 
#===============================================================================
187
 
class Demo(HasTraits):
188
 
    plot = Instance(Component)
189
 
 
190
 
    traits_view = View(
191
 
                    Group(
192
 
                        Item('plot', editor=ComponentEditor(size=size),
193
 
                             show_label=False),
194
 
                        orientation = "vertical"),
195
 
                    resizable=True, title=title
196
 
                    )
197
 
 
198
 
    def _plot_default(self):
199
 
         return _create_plot_component()
200
 
 
201
 
demo = Demo()
202
 
 
203
 
if __name__ == "__main__":
204
 
    demo.configure_traits()
205
 
 
206
 
#--EOF---