Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit eb4b3f8

Browse filesBrowse files
authored
remove ipywidget code from selectors and cleanup docstrings (#644)
* remove ipywidget code from linear selector and cleanup docstrings * remove ipywidget code from LinearRegionSelector, cleanup docstrings * remove a method * update API docs
1 parent a691be2 commit eb4b3f8
Copy full SHA for eb4b3f8

File tree

4 files changed

+51
-328
lines changed
Filter options

4 files changed

+51
-328
lines changed

‎docs/source/api/selectors/LinearRegionSelector.rst

Copy file name to clipboardExpand all lines: docs/source/api/selectors/LinearRegionSelector.rst
-2Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,12 +43,10 @@ Methods
4343

4444
LinearRegionSelector.add_axes
4545
LinearRegionSelector.add_event_handler
46-
LinearRegionSelector.add_ipywidget_handler
4746
LinearRegionSelector.clear_event_handlers
4847
LinearRegionSelector.get_selected_data
4948
LinearRegionSelector.get_selected_index
5049
LinearRegionSelector.get_selected_indices
51-
LinearRegionSelector.make_ipywidget_slider
5250
LinearRegionSelector.remove_event_handler
5351
LinearRegionSelector.rotate
5452
LinearRegionSelector.share_property

‎docs/source/api/selectors/LinearSelector.rst

Copy file name to clipboardExpand all lines: docs/source/api/selectors/LinearSelector.rst
-2Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,12 +43,10 @@ Methods
4343

4444
LinearSelector.add_axes
4545
LinearSelector.add_event_handler
46-
LinearSelector.add_ipywidget_handler
4746
LinearSelector.clear_event_handlers
4847
LinearSelector.get_selected_data
4948
LinearSelector.get_selected_index
5049
LinearSelector.get_selected_indices
51-
LinearSelector.make_ipywidget_slider
5250
LinearSelector.remove_event_handler
5351
LinearSelector.rotate
5452
LinearSelector.share_property
+28-167Lines changed: 28 additions & 167 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,16 @@
1-
from typing import *
21
import math
32
from numbers import Real
3+
from typing import Sequence
44

55
import numpy as np
66
import pygfx
77

8-
from ...utils.gui import IS_JUPYTER
98
from .._base import Graphic
109
from .._collection_base import GraphicCollection
1110
from .._features._selection_features import LinearSelectionFeature
1211
from ._base_selector import BaseSelector
1312

1413

15-
if IS_JUPYTER:
16-
# If using the jupyter backend, user has jupyter_rfb, and thus also ipywidgets
17-
import ipywidgets
18-
19-
2014
class LinearSelector(BaseSelector):
2115
@property
2216
def parent(self) -> Graphic:
@@ -39,11 +33,11 @@ def selection(self, value: int):
3933
self._selection.set_value(self, value)
4034

4135
@property
42-
def limits(self) -> Tuple[float, float]:
36+
def limits(self) -> tuple[float, float]:
4337
return self._limits
4438

4539
@limits.setter
46-
def limits(self, values: Tuple[float, float]):
40+
def limits(self, values: tuple[float, float]):
4741
# check that `values` is an iterable of two real numbers
4842
# using `Real` here allows it to work with builtin `int` and `float` types, and numpy scaler types
4943
if len(values) != 2 or not all(map(lambda v: isinstance(v, Real), values)):
@@ -62,46 +56,50 @@ def __init__(
6256
center: float,
6357
axis: str = "x",
6458
parent: Graphic = None,
65-
color: str | tuple = "w",
59+
color: str | Sequence[float] | np.ndarray = "w",
6660
thickness: float = 2.5,
6761
arrow_keys_modifier: str = "Shift",
6862
name: str = None,
6963
):
7064
"""
71-
Create a horizontal or vertical line slider that is synced to an ipywidget IntSlider
65+
Create a horizontal or vertical line that can be used to select a value along an axis.
7266
7367
Parameters
7468
----------
7569
selection: int
76-
initial x or y selected position for the slider, in world space
70+
initial x or y selected position for the selector, in data space
7771
7872
limits: (int, int)
79-
(min, max) limits along the x or y axis for the selector, in world space
73+
(min, max) limits along the x or y-axis for the selector, in data space
8074
81-
axis: str, default "x"
82-
"x" | "y", the axis which the slider can move along
75+
size: float
76+
size of the selector, usually the range of the data
8377
8478
center: float
85-
center offset of the selector on the orthogonal axis, by default the data mean
79+
center offset of the selector on the orthogonal axis, usually the data mean
80+
81+
axis: str, default "x"
82+
"x" | "y", the axis along which the selector can move
8683
8784
parent: Graphic
88-
parent graphic for this LineSelector
85+
parent graphic for this LinearSelector
8986
9087
arrow_keys_modifier: str
9188
modifier key that must be pressed to initiate movement using arrow keys, must be one of:
92-
"Control", "Shift", "Alt" or ``None``. Double click on the selector first to enable the
89+
"Control", "Shift", "Alt" or ``None``. Double-click the selector first to enable the
9390
arrow key movements, or set the attribute ``arrow_key_events_enabled = True``
9491
9592
thickness: float, default 2.5
96-
thickness of the slider
93+
thickness of the selector
9794
98-
color: Any, default "w"
99-
selection to set the color of the slider
95+
color: str | tuple | np.ndarray, default "w"
96+
color of the selector
10097
10198
name: str, optional
102-
name of line slider
99+
name of linear selector
103100
104101
"""
102+
105103
if len(limits) != 2:
106104
raise ValueError("limits must be a tuple of 2 integers, i.e. (int, int)")
107105

@@ -155,10 +153,6 @@ def __init__(
155153

156154
self._move_info: dict = None
157155

158-
self._block_ipywidget_call = False
159-
160-
self._handled_widgets = list()
161-
162156
if axis == "x":
163157
offset = (parent.offset[0], center + parent.offset[1], 0)
164158
elif axis == "y":
@@ -187,149 +181,22 @@ def __init__(
187181
else:
188182
self._selection.set_value(self, selection)
189183

190-
# update any ipywidgets
191-
self.add_event_handler(self._update_ipywidgets, "selection")
192-
193-
def _setup_ipywidget_slider(self, widget):
194-
# setup an ipywidget slider with bidirectional callbacks to this LinearSelector
195-
value = self.selection
196-
197-
if isinstance(widget, ipywidgets.IntSlider):
198-
value = int(value)
199-
200-
widget.value = value
201-
202-
# user changes widget -> linear selection changes
203-
widget.observe(self._ipywidget_callback, "value")
204-
205-
self._handled_widgets.append(widget)
206-
207-
def _update_ipywidgets(self, ev):
208-
# update the ipywidget sliders when LinearSelector value changes
209-
self._block_ipywidget_call = True # prevent infinite recursion
210-
211-
value = ev.info["value"]
212-
# update all the handled slider widgets
213-
for widget in self._handled_widgets:
214-
if isinstance(widget, ipywidgets.IntSlider):
215-
widget.value = int(value)
216-
else:
217-
widget.value = value
218-
219-
self._block_ipywidget_call = False
220-
221-
def _ipywidget_callback(self, change):
222-
# update the LinearSelector when the ipywidget value changes
223-
if self._block_ipywidget_call or self._moving:
224-
return
225-
226-
self.selection = change["new"]
227-
228-
def _fpl_add_plot_area_hook(self, plot_area):
229-
super()._fpl_add_plot_area_hook(plot_area=plot_area)
230-
231-
# resize the slider widgets when the canvas is resized
232-
self._plot_area.renderer.add_event_handler(self._set_slider_layout, "resize")
233-
234-
def _set_slider_layout(self, *args):
235-
w, h = self._plot_area.renderer.logical_size
236-
237-
for widget in self._handled_widgets:
238-
widget.layout = ipywidgets.Layout(width=f"{w}px")
239-
240-
def make_ipywidget_slider(self, kind: str = "IntSlider", **kwargs):
184+
def get_selected_index(self, graphic: Graphic = None) -> int | list[int]:
241185
"""
242-
Makes and returns an ipywidget slider that is associated to this LinearSelector
186+
Data index the selector is currently at w.r.t. the Graphic data.
243187
244-
Parameters
245-
----------
246-
kind: str
247-
"IntSlider", "FloatSlider" or "FloatLogSlider"
248-
249-
kwargs
250-
passed to the ipywidget slider constructor
251-
252-
Returns
253-
-------
254-
ipywidgets.Intslider or ipywidgets.FloatSlider
255-
256-
"""
257-
258-
if not IS_JUPYTER:
259-
raise ImportError(
260-
"Must installed `ipywidgets` to use `make_ipywidget_slider()`"
261-
)
262-
263-
if kind not in ["IntSlider", "FloatSlider", "FloatLogSlider"]:
264-
raise TypeError(
265-
f"`kind` must be one of: 'IntSlider', 'FloatSlider' or 'FloatLogSlider'\n"
266-
f"You have passed: '{kind}'"
267-
)
268-
269-
cls = getattr(ipywidgets, kind)
270-
271-
value = self.selection
272-
if "Int" in kind:
273-
value = int(self.selection)
274-
275-
slider = cls(
276-
min=self.limits[0],
277-
max=self.limits[1],
278-
value=value,
279-
**kwargs,
280-
)
281-
self.add_ipywidget_handler(slider)
282-
283-
return slider
284-
285-
def add_ipywidget_handler(self, widget, step: Union[int, float] = None):
286-
"""
287-
Bidirectionally connect events with a ipywidget slider
288-
289-
Parameters
290-
----------
291-
widget: ipywidgets.IntSlider, ipywidgets.FloatSlider, or ipywidgets.FloatLogSlider
292-
ipywidget slider to connect to
293-
294-
step: int or float, default ``None``
295-
step size, if ``None`` 100 steps are created
296-
297-
"""
298-
299-
if not isinstance(
300-
widget,
301-
(ipywidgets.IntSlider, ipywidgets.FloatSlider, ipywidgets.FloatLogSlider),
302-
):
303-
raise TypeError(
304-
f"`widget` must be one of: ipywidgets.IntSlider, ipywidgets.FloatSlider, or ipywidgets.FloatLogSlider\n"
305-
f"You have passed a: <{type(widget)}"
306-
)
307-
308-
if step is None:
309-
step = (self.limits[1] - self.limits[0]) / 100
310-
311-
if isinstance(widget, ipywidgets.IntSlider):
312-
step = int(step)
313-
314-
widget.step = step
315-
316-
self._setup_ipywidget_slider(widget)
317-
318-
def get_selected_index(self, graphic: Graphic = None) -> Union[int, List[int]]:
319-
"""
320-
Data index the slider is currently at w.r.t. the Graphic data. With LineGraphic data, the geometry x or y
321-
position is not always the data position, for example if plotting data using np.linspace. Use this to get
322-
the data index of the slider.
188+
With LineGraphic data, the geometry x or y position is not always the data position, for example if plotting
189+
data using np.linspace. Use this to get the data index of the selector.
323190
324191
Parameters
325192
----------
326193
graphic: Graphic, optional
327-
Graphic to get the selected data index from. Default is the parent graphic associated to the slider.
194+
Graphic to get the selected data index from. Default is the parent graphic associated to the selector.
328195
329196
Returns
330197
-------
331198
int or List[int]
332-
data index the slider is currently at, list of ``int`` if a Collection
199+
data index the selector is currently at, list of ``int`` if a Collection
333200
"""
334201

335202
source = self._get_source(graphic)
@@ -354,10 +221,10 @@ def _get_selected_index(self, graphic):
354221
"Line" in graphic.__class__.__name__
355222
or "Scatter" in graphic.__class__.__name__
356223
):
357-
# we want to find the index of the data closest to the slider position
224+
# we want to find the index of the data closest to the selector position
358225
find_value = self.selection
359226

360-
# get closest data index to the world space position of the slider
227+
# get closest data index to the world space position of the selector
361228
idx = np.searchsorted(data, find_value, side="left")
362229

363230
if idx > 0 and (
@@ -398,9 +265,3 @@ def _move_graphic(self, delta: np.ndarray):
398265
self.selection = self.selection + delta[0]
399266
else:
400267
self.selection = self.selection + delta[1]
401-
402-
def _fpl_prepare_del(self):
403-
for widget in self._handled_widgets:
404-
widget.unobserve(self._ipywidget_callback, "value")
405-
406-
super()._fpl_prepare_del()

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.