Skip to content

select_traces selector argument can now be a function #2836

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

Merged
merged 1 commit into from
Oct 20, 2020
Merged
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
17 changes: 13 additions & 4 deletions packages/python/plotly/plotly/basedatatypes.py
Original file line number Diff line number Diff line change
Expand Up @@ -804,10 +804,19 @@ def _perform_select_traces(self, filter_by_subplot, grid_subplot_refs, selector)
continue

# Filter by selector
if not self._selector_matches(trace, selector):
continue

yield trace
# If selector is a dict, call self._selector_matches
if type(selector) == type(dict()):
trace_matches = self._selector_matches(trace, selector)
# If selector is a function, call it with the trace as the argument
elif type(selector) == type(lambda x: True):
trace_matches = selector(trace)
else:
raise TypeError(
"selector must be dict or a function "
"accepting a trace returning a boolean."
)
if trace_matches:
yield trace

@staticmethod
def _selector_matches(obj, selector):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,43 @@ def test_select_property_and_grid(self):
# Valid row/col and valid selector but the intersection is empty
self.assert_select_traces([], selector={"type": "markers"}, row=3, col=1)

def test_select_with_function(self):
def _check_trace_key(k, v):
def f(t):
try:
return t[k] == v
except LookupError:
return False

return f

# (1, 1)
self.assert_select_traces(
[0], selector=_check_trace_key("mode", "markers"), row=1, col=1
)
self.assert_select_traces(
[1], selector=_check_trace_key("type", "bar"), row=1, col=1
)

# (2, 1)
self.assert_select_traces(
[2, 9], selector=_check_trace_key("mode", "lines"), row=2, col=1
)

# (1, 2)
self.assert_select_traces(
[4], selector=_check_trace_key("marker.color", "green"), row=1, col=2
)

# Valid row/col and valid selector but the intersection is empty
self.assert_select_traces(
[], selector=_check_trace_key("type", "markers"), row=3, col=1
)

def test_select_traces_type_error(self):
with self.assertRaises(TypeError):
self.assert_select_traces([0], selector=123, row=1, col=1)

def test_for_each_trace_lowercase_names(self):
# Names are all uppercase to start
original_names = [t.name for t in self.fig.data]
Expand Down