-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathplot.py
More file actions
259 lines (211 loc) · 6.94 KB
/
plot.py
File metadata and controls
259 lines (211 loc) · 6.94 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
# -*- coding: utf-8 -*-# -*- coding: utf-8 -*-
#
# Licensed under the terms of the BSD 3-Clause
# (see plotpy/LICENSE for details)
"""Plot tools"""
from __future__ import annotations
from typing import TYPE_CHECKING
from guidata.configtools import get_icon
from guidata.qthelpers import add_actions, add_separator
from qtpy import QtCore as QC
from qtpy import QtWidgets as QW
from plotpy.config import _
from plotpy.constants import PARAMETERS_TITLE_ICON
from plotpy.events import ZoomRectHandler, setup_standard_tool_filter
from plotpy.interfaces import IImageItemType, IShapeItemType
from plotpy.items import RectangleShape, get_items_in_rectangle
from plotpy.tools.base import (
CommandTool,
DefaultToolbarID,
GuiTool,
InteractiveTool,
RectangularActionTool,
)
if TYPE_CHECKING:
from plotpy.plot import BasePlot, PlotManager
class DoAutoscaleTool(CommandTool):
"""A tool to perform autoscale for associated plot."""
def __init__(
self,
manager,
title=_("AutoScale"),
icon="autoscale.png",
tip=None,
toolbar_id=DefaultToolbarID,
):
super().__init__(
manager, title=title, icon=icon, tip=tip, toolbar_id=toolbar_id
)
def setup_context_menu(self, menu: QW.QMenu, plot: BasePlot) -> None:
"""
Set up the context menu for the tool.
Args:
menu: Context menu
plot: Plot instance
"""
pass
def activate_command(self, plot: BasePlot, checked: bool) -> None:
"""
Activate tool.
Args:
plot: Plot instance
checked: Whether the tool is checked
"""
if checked:
plot.do_autoscale()
class BasePlotMenuTool(CommandTool):
"""
A tool that gather parameter panels from the BasePlot
and proposes to edit them and set them back
"""
def __init__(
self, manager, key, title=None, icon=None, tip=None, toolbar_id=DefaultToolbarID
):
default_title, default_icon = PARAMETERS_TITLE_ICON[key]
if title is None:
title = default_title
if icon is None:
icon = default_icon
super().__init__(manager, title, icon, tip, toolbar_id)
# Warning: icon (str) --(Base class constructor)--> self.icon (QIcon)
self.key = key
def activate_command(self, plot: BasePlot, checked: bool) -> None:
"""
Activate tool.
Args:
plot: Plot instance
checked: Whether the tool is checked
"""
plot.edit_plot_parameters(self.key)
def update_status(self, plot: BasePlot) -> None:
"""
Update the status of the tool.
Args:
plot: Plot instance
"""
status = plot.get_plot_parameters_status(self.key)
self.action.setEnabled(status)
class DisplayCoordsTool(CommandTool):
"""Tool for displaying coordinates."""
def __init__(self, manager):
super().__init__(
manager,
_("Markers"),
icon=get_icon("on_curve.png"),
tip=None,
toolbar_id=None,
)
self.action.setEnabled(True)
def create_action_menu(self, manager: PlotManager) -> QW.QMenu:
"""
Create and return menu for the tool's action.
Args:
manager: Plot manager
Returns:
Menu for the tool's action
"""
menu = QW.QMenu()
self.canvas_act = manager.create_action(
_("Free"), toggled=self.activate_canvas_pointer
)
self.curve_act = manager.create_action(
_("Bound to active item"), toggled=self.activate_curve_pointer
)
add_actions(menu, (self.canvas_act, self.curve_act))
return menu
def activate_canvas_pointer(self, enable: bool) -> None:
"""
Activate canvas pointer.
Args:
enable: Whether to enable the canvas pointer
"""
plot = self.get_active_plot()
if plot is not None:
plot.set_pointer("canvas" if enable else None)
def activate_curve_pointer(self, enable: bool) -> None:
"""
Activate curve pointer.
Args:
enable: Whether to enable the curve pointer
"""
plot = self.get_active_plot()
if plot is not None:
plot.set_pointer("curve" if enable else None)
def update_status(self, plot: BasePlot) -> None:
"""
Update the status of the tool.
Args:
plot: Plot instance
"""
self.canvas_act.setChecked(plot.canvas_pointer)
self.curve_act.setChecked(plot.curve_pointer)
class RectZoomTool(InteractiveTool):
TITLE = _("Rectangle zoom")
ICON = "magnifier.png"
def setup_filter(self, baseplot):
"""
:param baseplot:
:return:
"""
filter = baseplot.filter
start_state = filter.new_state()
handler = ZoomRectHandler(
filter, QC.Qt.MouseButton.LeftButton, start_state=start_state
)
shape, h0, h1 = self.get_shape()
handler.set_shape(shape, h0, h1)
return setup_standard_tool_filter(filter, start_state)
def get_shape(self):
"""
:return:
"""
shape = RectangleShape(0, 0, 1, 1)
shape.set_style("plot", "shape/rectzoom")
return shape, 0, 2
class DummySeparatorTool(GuiTool):
""" """
def __init__(self, manager, toolbar_id=DefaultToolbarID):
super().__init__(manager, toolbar_id)
def setup_toolbar(self, toolbar):
"""Setup tool's toolbar"""
add_separator(toolbar)
def setup_context_menu(self, menu, plot):
"""
:param menu:
:param plot:
"""
add_separator(menu)
class RectangularSelectionTool(RectangularActionTool):
SWITCH_TO_DEFAULT_TOOL = True
TITLE = _("Rectangular selection tool")
ICON = "select_area.svg"
def __init__(self, manager, intersect=True, toolbar_id=DefaultToolbarID):
super().__init__(
manager, self.select_items, toolbar_id=toolbar_id, fix_orientation=True
)
self.intersect = intersect
def select_items(self, plot, p0, p1):
items_to_select = []
# select items that implement IShapeItemType (annotation shapes, ...)
items = get_items_in_rectangle(
plot,
p0,
p1,
item_type=IShapeItemType,
intersect=self.intersect,
)
for item in items:
if item.isVisible():
items_to_select.append(item)
# select items that implement IExportROIImageItemType (TrImageItem, ...)
items = get_items_in_rectangle(
plot,
p0,
p1,
item_type=IImageItemType,
intersect=self.intersect,
)
for item in items:
if item.isVisible():
items_to_select.append(item)
plot.select_some_items(items_to_select)