Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement Widget.from_values #7033

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions panel/util/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -503,3 +503,15 @@ def safe_next():
if value is done:
break
yield value


def unique_iterator(seq):
"""
Returns an iterator containing all non-duplicate elements
in the input sequence.
"""
seen = set()
for item in seq:
if item not in seen:
seen.add(item)
yield item
29 changes: 29 additions & 0 deletions panel/widgets/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
TYPE_CHECKING, Any, Callable, ClassVar, Mapping, Optional, TypeVar,
)

import numpy as np
import param # type: ignore

from bokeh.models import ImportedStyleSheet, Tooltip
Expand All @@ -20,6 +21,7 @@
from .._param import Margin
from ..layout.base import Row
from ..reactive import Reactive
from ..util import unique_iterator
from ..viewable import Layoutable, Viewable

if TYPE_CHECKING:
Expand Down Expand Up @@ -68,6 +70,33 @@ def from_param(cls: type[T], parameter: param.Parameter, **params) -> T:
)
return layout[0]

@classmethod
def _infer_params(cls, values, **params):
if 'name' not in params and hasattr(values, 'name'):
params['name'] = values.name
if 'start' in cls.param and 'start' not in params:
params['start'] = np.nanmin(values)
if 'end' in cls.param and 'end' not in params:
params['end'] = np.nanmax(values)
if 'options' in cls.param and 'options' not in params:
params['options'] = list(unique_iterator(values))
return params

@classmethod
def from_values(cls, values, **params):
"""
Creates an instance of this Widget where the parameters are
inferred from the data.

Arguments
---------
values: Iterable
The values to infer the parameters from.
params: dict
Additional parameters to pass to the widget.
"""
return cls(**cls._infer_params(values, **params))

@property
def rx(self):
return self.param.value.rx
Expand Down
1 change: 0 additions & 1 deletion panel/widgets/slider.py
Original file line number Diff line number Diff line change
Expand Up @@ -529,7 +529,6 @@ def values(self):
return list(self.options.values()) if isinstance(self.options, dict) else self.options



class _RangeSliderBase(_SliderBase):

value = param.Tuple(default=(None, None), length=2, allow_None=False, nested_refs=True, doc="""
Expand Down
Loading