interactive-figure 0.3.3__py3-none-any.whl → 0.3.5__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of interactive-figure might be problematic. Click here for more details.
- interactive_figure/__about__.py +1 -1
- interactive_figure/interactive_figure.py +318 -326
- {interactive_figure-0.3.3.dist-info → interactive_figure-0.3.5.dist-info}/METADATA +8 -18
- interactive_figure-0.3.5.dist-info/RECORD +7 -0
- {interactive_figure-0.3.3.dist-info → interactive_figure-0.3.5.dist-info}/WHEEL +1 -1
- {interactive_figure-0.3.3.dist-info → interactive_figure-0.3.5.dist-info}/licenses/LICENSE.txt +7 -7
- interactive_figure-0.3.3.dist-info/RECORD +0 -7
interactive_figure/__about__.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = "0.3.
|
|
1
|
+
__version__ = "0.3.5"
|
|
@@ -1,326 +1,318 @@
|
|
|
1
|
-
"""
|
|
2
|
-
This module provides functions to create and interact with a Matplotlib figure.
|
|
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
|
-
if
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
_state.
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
#
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
#
|
|
54
|
-
#
|
|
55
|
-
#
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
fig.canvas.
|
|
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
|
-
def
|
|
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
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
_state.
|
|
279
|
-
_state.
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
def
|
|
283
|
-
"""
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
"""
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
_state = SimpleNamespace(
|
|
320
|
-
fig=None,
|
|
321
|
-
ax=None,
|
|
322
|
-
last_keypress=None,
|
|
323
|
-
last_mousepress=None,
|
|
324
|
-
last_mouse_x=None,
|
|
325
|
-
last_mouse_y=None,
|
|
326
|
-
)
|
|
1
|
+
"""
|
|
2
|
+
This module provides functions to create and interact with a Matplotlib figure. The figure registers mouse presses, keyboard input and the location of the mouse
|
|
3
|
+
after any input.
|
|
4
|
+
|
|
5
|
+
Source: https://github.com/teuncm/interactive-figure
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import matplotlib.pyplot as plt
|
|
9
|
+
from types import SimpleNamespace
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def create(aspect_ratio="auto", hide_toolbar=False, **kwargs):
|
|
13
|
+
"""Create the interactive figure.
|
|
14
|
+
|
|
15
|
+
Parameters
|
|
16
|
+
----------
|
|
17
|
+
aspect_ratio : str, optional
|
|
18
|
+
aspect ratio of the Axes, default "auto".
|
|
19
|
+
hide_toolbar : bool, optional
|
|
20
|
+
whether to hide the toolbar, default False.
|
|
21
|
+
|
|
22
|
+
Remaining arguments will be sent to the figure upon creation.
|
|
23
|
+
|
|
24
|
+
Raises
|
|
25
|
+
----------
|
|
26
|
+
RuntimeError
|
|
27
|
+
if multiple interactive figures are created.
|
|
28
|
+
"""
|
|
29
|
+
if _state.fig is None:
|
|
30
|
+
if hide_toolbar:
|
|
31
|
+
plt.rcParams["toolbar"] = "None"
|
|
32
|
+
|
|
33
|
+
# Disable interactive mode for explicit control over drawing. See:
|
|
34
|
+
# https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.isinteractive.html#matplotlib.pyplot.isinteractive
|
|
35
|
+
plt.ioff()
|
|
36
|
+
|
|
37
|
+
_state.fig = fig = plt.figure(**kwargs)
|
|
38
|
+
fig.canvas.manager.set_window_title("Interactive Figure")
|
|
39
|
+
# Create drawable axis.
|
|
40
|
+
_state.ax = ax = plt.gca()
|
|
41
|
+
ax.set_aspect(aspect_ratio)
|
|
42
|
+
|
|
43
|
+
# Show figure but allow the main thread to continue.
|
|
44
|
+
plt.show(block=False)
|
|
45
|
+
|
|
46
|
+
# Reset plot state and draw to obtain focus.
|
|
47
|
+
clear()
|
|
48
|
+
draw()
|
|
49
|
+
|
|
50
|
+
# Add our custom event handlers. For handlers, see:
|
|
51
|
+
# https://matplotlib.org/stable/api/backend_bases_api.html#matplotlib.backend_bases.FigureCanvasBase.mpl_connect
|
|
52
|
+
# For general interaction handling, see:
|
|
53
|
+
# https://matplotlib.org/stable/users/explain/figure/interactive_guide.html
|
|
54
|
+
# For mouse buttons, see:
|
|
55
|
+
# https://matplotlib.org/stable/api/backend_bases_api.html#matplotlib.backend_bases.MouseButton
|
|
56
|
+
fig.canvas.mpl_disconnect(fig.canvas.manager.key_press_handler_id)
|
|
57
|
+
fig.canvas.mpl_disconnect(fig.canvas.manager.button_press_handler_id)
|
|
58
|
+
fig.canvas.mpl_connect("key_press_event", _key_press_handler)
|
|
59
|
+
fig.canvas.mpl_connect("button_press_event", _button_press_handler)
|
|
60
|
+
|
|
61
|
+
print("Successfully created the interactive figure.")
|
|
62
|
+
else:
|
|
63
|
+
raise RuntimeError("Error: you cannot create multiple interactive figures.")
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def draw():
|
|
67
|
+
"""Draw contents of the figure."""
|
|
68
|
+
_check_exists()
|
|
69
|
+
|
|
70
|
+
canvas = _state.fig.canvas
|
|
71
|
+
# Mark canvas for a draw.
|
|
72
|
+
canvas.draw_idle()
|
|
73
|
+
# Force update the GUI. This is when the drawing actually happens
|
|
74
|
+
# in the backend.
|
|
75
|
+
canvas.flush_events()
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def clear(hide_labels=False, set_limits=True):
|
|
79
|
+
"""Reset contents and layout of the figure.
|
|
80
|
+
|
|
81
|
+
Parameters
|
|
82
|
+
----------
|
|
83
|
+
set_limits : bool, optional
|
|
84
|
+
set the Axes limits to [0, 100].
|
|
85
|
+
hide_labels : bool, optional
|
|
86
|
+
remove all labels from the figure.
|
|
87
|
+
"""
|
|
88
|
+
_check_exists()
|
|
89
|
+
|
|
90
|
+
ax = _state.ax
|
|
91
|
+
ax.clear()
|
|
92
|
+
|
|
93
|
+
if set_limits:
|
|
94
|
+
ax.set_xlim([0, 100])
|
|
95
|
+
ax.set_ylim([0, 100])
|
|
96
|
+
|
|
97
|
+
if hide_labels:
|
|
98
|
+
ax.set_xticks([])
|
|
99
|
+
ax.set_yticks([])
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
def toggle_fullscreen():
|
|
103
|
+
"""Toggle fullscreen."""
|
|
104
|
+
_check_exists()
|
|
105
|
+
|
|
106
|
+
_state.figure.canvas.manager.full_screen_toggle()
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
def close():
|
|
110
|
+
"""Close the figure."""
|
|
111
|
+
_check_exists()
|
|
112
|
+
|
|
113
|
+
plt.close(_state.fig)
|
|
114
|
+
|
|
115
|
+
_state_reset_fig()
|
|
116
|
+
_state_reset_press()
|
|
117
|
+
|
|
118
|
+
print("Successfully closed the interactive figure.")
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
def wait_for_interaction(timeout=-1):
|
|
122
|
+
"""Wait for interaction.
|
|
123
|
+
|
|
124
|
+
Optionally use a timeout in seconds.
|
|
125
|
+
|
|
126
|
+
Parameters
|
|
127
|
+
----------
|
|
128
|
+
timeout : int, optional
|
|
129
|
+
Timeout in seconds when waiting for input.
|
|
130
|
+
|
|
131
|
+
Returns
|
|
132
|
+
-------
|
|
133
|
+
bool | None
|
|
134
|
+
- True if a key was pressed.
|
|
135
|
+
- False if a mouse button was pressed.
|
|
136
|
+
- None if no input was given within the timeout.
|
|
137
|
+
"""
|
|
138
|
+
_check_exists()
|
|
139
|
+
|
|
140
|
+
# Reimplementation of:
|
|
141
|
+
# figure.Figure.waitforbuttonpress()
|
|
142
|
+
# _blocking_input.blocking_input_loop()
|
|
143
|
+
# but without show() to prevent redrawing the figure.
|
|
144
|
+
|
|
145
|
+
# Contains the event that was registered.
|
|
146
|
+
event = None
|
|
147
|
+
|
|
148
|
+
# Handler to stop blocking event loop.
|
|
149
|
+
def simple_handler(ev):
|
|
150
|
+
nonlocal event
|
|
151
|
+
event = ev
|
|
152
|
+
_state.fig.canvas.stop_event_loop()
|
|
153
|
+
|
|
154
|
+
# Connect event handlers and save callback ids.
|
|
155
|
+
callback_ids = [
|
|
156
|
+
_state.fig.canvas.mpl_connect(name, simple_handler) for name in ["button_press_event", "key_press_event"]
|
|
157
|
+
]
|
|
158
|
+
try:
|
|
159
|
+
# Start a blocking event loop.
|
|
160
|
+
_state.fig.canvas.start_event_loop(timeout=timeout)
|
|
161
|
+
finally:
|
|
162
|
+
# Disconnect handlers.
|
|
163
|
+
for callback_id in callback_ids:
|
|
164
|
+
_state.fig.canvas.mpl_disconnect(callback_id)
|
|
165
|
+
|
|
166
|
+
interaction_type = None if event is None else event.name == "key_press_event"
|
|
167
|
+
|
|
168
|
+
if interaction_type is None:
|
|
169
|
+
# No button was pressed, so reset the state.
|
|
170
|
+
_state_reset_press()
|
|
171
|
+
|
|
172
|
+
return interaction_type
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
def get_last_key_press():
|
|
176
|
+
"""Get the last key press in lowercase.
|
|
177
|
+
|
|
178
|
+
Returns
|
|
179
|
+
-------
|
|
180
|
+
str | None
|
|
181
|
+
The last key that was pressed.
|
|
182
|
+
"""
|
|
183
|
+
_check_exists()
|
|
184
|
+
|
|
185
|
+
key_string = _state.last_keypress
|
|
186
|
+
|
|
187
|
+
if key_string is None:
|
|
188
|
+
return None
|
|
189
|
+
else:
|
|
190
|
+
return key_string.lower()
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
def get_last_mouse_press():
|
|
194
|
+
"""Get the ID of the last mouse press.
|
|
195
|
+
|
|
196
|
+
Returns
|
|
197
|
+
-------
|
|
198
|
+
int | None
|
|
199
|
+
The identifier of the last mouse button that was pressed.
|
|
200
|
+
"""
|
|
201
|
+
_check_exists()
|
|
202
|
+
|
|
203
|
+
mouse_button = _state.last_mousepress
|
|
204
|
+
|
|
205
|
+
if mouse_button is None:
|
|
206
|
+
return None
|
|
207
|
+
else:
|
|
208
|
+
return mouse_button.value
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
def get_last_mouse_pos():
|
|
212
|
+
"""Get the last mouse position.
|
|
213
|
+
|
|
214
|
+
Returns
|
|
215
|
+
-------
|
|
216
|
+
(x: float, y: float) | (None, None)
|
|
217
|
+
The last registered mouse position after any interaction.
|
|
218
|
+
"""
|
|
219
|
+
_check_exists()
|
|
220
|
+
|
|
221
|
+
return (_state.last_mouse_x, _state.last_mouse_y)
|
|
222
|
+
|
|
223
|
+
|
|
224
|
+
def wait(timeout):
|
|
225
|
+
"""Freeze for the given number of seconds.
|
|
226
|
+
|
|
227
|
+
During this period it is not possible to interact
|
|
228
|
+
with the figure. For sub-second timeouts use time.wait() instead.
|
|
229
|
+
|
|
230
|
+
Parameters
|
|
231
|
+
----------
|
|
232
|
+
timeout : float
|
|
233
|
+
Number of seconds to wait for.
|
|
234
|
+
"""
|
|
235
|
+
_check_exists()
|
|
236
|
+
|
|
237
|
+
_state.fig.canvas.start_event_loop(timeout=timeout)
|
|
238
|
+
# No button was pressed, so reset the state.
|
|
239
|
+
_state_reset_press()
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
# HIDDEN METHODS
|
|
243
|
+
|
|
244
|
+
|
|
245
|
+
def _get_state():
|
|
246
|
+
"""Get all state information of the interactive figure.
|
|
247
|
+
|
|
248
|
+
Returns
|
|
249
|
+
-------
|
|
250
|
+
SimpleNamespace
|
|
251
|
+
Namespace with figure state information
|
|
252
|
+
"""
|
|
253
|
+
return _state
|
|
254
|
+
|
|
255
|
+
|
|
256
|
+
def _check_exists():
|
|
257
|
+
"""Check if the interactive figure exists.
|
|
258
|
+
|
|
259
|
+
Raises
|
|
260
|
+
------
|
|
261
|
+
RuntimeError
|
|
262
|
+
If the figure is not available
|
|
263
|
+
"""
|
|
264
|
+
if _state.fig is None:
|
|
265
|
+
raise RuntimeError("Error: the interactive figure is not available.")
|
|
266
|
+
|
|
267
|
+
|
|
268
|
+
def _state_reset_fig():
|
|
269
|
+
"""Reset figure information."""
|
|
270
|
+
_state.fig = None
|
|
271
|
+
_state.ax = None
|
|
272
|
+
|
|
273
|
+
|
|
274
|
+
def _state_reset_press():
|
|
275
|
+
"""Reset last registered press information."""
|
|
276
|
+
_state.last_keypress = None
|
|
277
|
+
_state.last_mousepress = None
|
|
278
|
+
_state.last_mouse_x = None
|
|
279
|
+
_state.last_mouse_y = None
|
|
280
|
+
|
|
281
|
+
|
|
282
|
+
def _key_press_handler(event):
|
|
283
|
+
"""Register key and mouse coordinates on press.
|
|
284
|
+
|
|
285
|
+
Parameters
|
|
286
|
+
----------
|
|
287
|
+
event
|
|
288
|
+
The event object that was generated internally
|
|
289
|
+
"""
|
|
290
|
+
_state.last_keypress = event.key
|
|
291
|
+
_state.last_mousepress = None
|
|
292
|
+
_state.last_mouse_x = event.xdata
|
|
293
|
+
_state.last_mouse_y = event.ydata
|
|
294
|
+
|
|
295
|
+
|
|
296
|
+
def _button_press_handler(event):
|
|
297
|
+
"""Register key, mouse button and mouse coordinates on press.
|
|
298
|
+
|
|
299
|
+
Parameters
|
|
300
|
+
----------
|
|
301
|
+
event
|
|
302
|
+
The event object that was generated internally
|
|
303
|
+
"""
|
|
304
|
+
_state.last_keypress = event.key
|
|
305
|
+
_state.last_mousepress = event.button
|
|
306
|
+
_state.last_mouse_x = event.xdata
|
|
307
|
+
_state.last_mouse_y = event.ydata
|
|
308
|
+
|
|
309
|
+
|
|
310
|
+
# Namespace to track the internal state of the interactive figure.
|
|
311
|
+
_state = SimpleNamespace(
|
|
312
|
+
fig=None,
|
|
313
|
+
ax=None,
|
|
314
|
+
last_keypress=None,
|
|
315
|
+
last_mousepress=None,
|
|
316
|
+
last_mouse_x=None,
|
|
317
|
+
last_mouse_y=None,
|
|
318
|
+
)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
2
|
Name: interactive-figure
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.5
|
|
4
4
|
Summary: Create interactive Matplotlib figures!
|
|
5
5
|
Project-URL: Documentation, https://teuncm.github.io/interactive-figure/autoapi/interactive_figure/interactive_figure/index.html
|
|
6
6
|
Project-URL: Issues, https://github.com/teuncm/interactive-figure/issues
|
|
@@ -38,29 +38,15 @@ pip install interactive-figure
|
|
|
38
38
|
from interactive_figure import interactive_figure
|
|
39
39
|
|
|
40
40
|
interactive_figure.create()
|
|
41
|
-
#
|
|
41
|
+
# Wait until user input is received.
|
|
42
42
|
interactive_figure.wait_for_interaction()
|
|
43
|
-
key = interactive_figure.
|
|
43
|
+
key = interactive_figure.get_last_key_press()
|
|
44
44
|
print(f"Pressed key: {key}")
|
|
45
45
|
interactive_figure.close()
|
|
46
46
|
```
|
|
47
47
|
|
|
48
48
|
Demos can be found in the *demo* folder on GitHub.
|
|
49
49
|
|
|
50
|
-
## Functionality
|
|
51
|
-
|
|
52
|
-
#### User interaction
|
|
53
|
-
- Capture key presses, button presses and mouse location
|
|
54
|
-
|
|
55
|
-
#### Figure control
|
|
56
|
-
- Create
|
|
57
|
-
- Toggle fullscreen
|
|
58
|
-
- Clear
|
|
59
|
-
- Wait
|
|
60
|
-
- Wait for interaction (optionally timeout)
|
|
61
|
-
- Draw
|
|
62
|
-
- Close
|
|
63
|
-
|
|
64
50
|
## Limitations
|
|
65
51
|
|
|
66
52
|
- Waiting for user input will not work in Jupyter Notebooks and the interactive interpreter due to the way Matplotlib handles events.
|
|
@@ -74,8 +60,12 @@ pipx install hatch
|
|
|
74
60
|
hatch shell
|
|
75
61
|
|
|
76
62
|
# Build
|
|
63
|
+
hatch version fix
|
|
77
64
|
hatch build -c
|
|
78
65
|
./generate_docs.sh
|
|
66
|
+
|
|
67
|
+
# Publish
|
|
68
|
+
hatch publish
|
|
79
69
|
```
|
|
80
70
|
|
|
81
71
|
## Links
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
interactive_figure/__about__.py,sha256=hu_23GWCWpKjdw97-0y_O7JlxUWN4apUKOL4q5xXd7Q,23
|
|
2
|
+
interactive_figure/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
3
|
+
interactive_figure/interactive_figure.py,sha256=hvQX5OACBYoz5EK9Wd3aOZm6I79ia6PGg69CtkPl_Mo,8410
|
|
4
|
+
interactive_figure-0.3.5.dist-info/METADATA,sha256=WYQ6OrtTdjiUS3npBEhymGvE5Fc2Pc7PxLBPGCYr-4U,2438
|
|
5
|
+
interactive_figure-0.3.5.dist-info/WHEEL,sha256=1yFddiXMmvYK7QYTqtRNtX66WJ0Mz8PYEiEUoOUUxRY,87
|
|
6
|
+
interactive_figure-0.3.5.dist-info/licenses/LICENSE.txt,sha256=R6IpPdPKA5nLHPKRXIhlFHLE59dMUtve0qeXhZPr0Hk,1043
|
|
7
|
+
interactive_figure-0.3.5.dist-info/RECORD,,
|
{interactive_figure-0.3.3.dist-info → interactive_figure-0.3.5.dist-info}/licenses/LICENSE.txt
RENAMED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
4
|
-
|
|
5
|
-
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
6
|
-
|
|
7
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
4
|
+
|
|
5
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
6
|
+
|
|
7
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
interactive_figure/__about__.py,sha256=8KcCYTXH99C2-gCLuPILJvtT9YftRWJsartIx6TQ2ZY,22
|
|
2
|
-
interactive_figure/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
3
|
-
interactive_figure/interactive_figure.py,sha256=rc73FSaCdyErSDnJ8xdPiSWzROCOhjLnv-Ex2QGO4ZU,8357
|
|
4
|
-
interactive_figure-0.3.3.dist-info/METADATA,sha256=G0OtQklXD3z93CoEDZrGSJrsSkWU20uDnxFXJYdKimA,2617
|
|
5
|
-
interactive_figure-0.3.3.dist-info/WHEEL,sha256=9QBuHhg6FNW7lppboF2vKVbCGTVzsFykgRQjjlajrhA,87
|
|
6
|
-
interactive_figure-0.3.3.dist-info/licenses/LICENSE.txt,sha256=WvwiBQtt_VVnf6szbVDxrAuRc6U6TLa7mbnvJSWzMGw,1036
|
|
7
|
-
interactive_figure-0.3.3.dist-info/RECORD,,
|