diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 7f2a88ba..28b6bdc5 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -26,6 +26,12 @@ jobs: matrix: os: ['windows-latest', 'macOS-latest', 'ubuntu-latest'] python-version: ['3.7', '3.8', '3.9', '3.10', '3.11', '3.12'] + exclude: # Python < 3.8 is not supported on Apple Silicon ARM64 + - os: macOS-latest + python-version: '3.7' + include: # So run on older version on Intel CPU + - os: macOS-13 + python-version: '3.7' defaults: run: shell: bash diff --git a/plotly_resampler/figure_resampler/figure_resampler_interface.py b/plotly_resampler/figure_resampler/figure_resampler_interface.py index 25ce4009..b296cfb2 100644 --- a/plotly_resampler/figure_resampler/figure_resampler_interface.py +++ b/plotly_resampler/figure_resampler/figure_resampler_interface.py @@ -980,21 +980,21 @@ def add_trace( uuid_str = str(uuid4()) if trace.uid is None else trace.uid trace.uid = uuid_str - # construct the hf_data_container - # TODO in future version -> maybe regex on kwargs which start with `hf_` - dc = self._parse_get_trace_props( - trace, - hf_x, - hf_y, - hf_text, - hf_hovertext, - hf_marker_size, - hf_marker_color, - ) - # These traces will determine the autoscale its RANGE! # -> so also store when `limit_to_view` is set. if trace["type"].lower() in self._high_frequency_traces: + # construct the hf_data_container + # TODO in future version -> maybe regex on kwargs which start with `hf_` + dc = self._parse_get_trace_props( + trace, + hf_x, + hf_y, + hf_text, + hf_hovertext, + hf_marker_size, + hf_marker_color, + ) + n_samples = len(dc.x) if n_samples > max_out_s or limit_to_view: self._print( diff --git a/plotly_resampler/figure_resampler/figurewidget_resampler.py b/plotly_resampler/figure_resampler/figurewidget_resampler.py index ef8d871c..a8ed643d 100644 --- a/plotly_resampler/figure_resampler/figurewidget_resampler.py +++ b/plotly_resampler/figure_resampler/figurewidget_resampler.py @@ -254,27 +254,30 @@ def _update_spike_ranges(self, layout, *showspikes, force_update=False): # Construct the update data update_data = self._construct_update_data(relayout_dict) - if self._print_verbose: - self._relayout_hist.append(layout) - self._relayout_hist.append(["showspikes-update", len(update_data) - 1]) - self._relayout_hist.append("-" * 30) - - with self.batch_update(): - # First update the layout (first item of update_data) - if not force_update: - self.layout.update(self._parse_relayout(update_data[0])) - - # Also: Remove the showspikes from the layout, otherwise the autorange - # will not work as intended (it will not be triggered again) - # Note: this removal causes a second trigger of this method - # which will go in the "else" part below. - for xaxis_str in self._xaxis_list: - self.layout[xaxis_str].pop("showspikes") + if not self._is_no_update(update_data): + if self._print_verbose: + self._relayout_hist.append(layout) + self._relayout_hist.append( + ["showspikes-update", len(update_data) - 1] + ) + self._relayout_hist.append("-" * 30) + + with self.batch_update(): + # First update the layout (first item of update_data) + if not force_update: + self.layout.update(self._parse_relayout(update_data[0])) + + # Also: Remove the showspikes from the layout, otherwise the autorange + # will not work as intended (it will not be triggered again) + # Note: this removal causes a second trigger of this method + # which will go in the "else" part below. + for xaxis_str in self._xaxis_list: + self.layout[xaxis_str].pop("showspikes") - # Then, update the data - for updated_trace in update_data[1:]: - trace_idx = updated_trace.pop("index") - self.data[trace_idx].update(updated_trace) + # Then, update the data + for updated_trace in update_data[1:]: + trace_idx = updated_trace.pop("index") + self.data[trace_idx].update(updated_trace) elif self._print_verbose: self._relayout_hist.append(["showspikes", "initial call or showspikes"]) self._relayout_hist.append("-" * 40) diff --git a/tests/fr_selenium.py b/tests/fr_selenium.py index 659d7581..9db71c4b 100644 --- a/tests/fr_selenium.py +++ b/tests/fr_selenium.py @@ -136,7 +136,7 @@ def browser_independent_single_callback_request_assert( # There are 2 requests which are send # 1. first: changed-layout to server -> new data to back-end request # 2. the front-end relayout request - assert len(requests) >= 1 + assert len(requests) >= 1, f"len(requests) = {len(requests)}" if len(requests) == 2: fetch_data_request, relayout_request = requests # RequestParser.assert_front_end_relayout_request(relayout_request) @@ -146,7 +146,7 @@ def browser_independent_single_callback_request_assert( elif "chrome" in browser_name: # for some, yet unknown reason, chrome does not seem to capture the # second front-end request. - assert len(requests) == 1 + assert len(requests) == 1, f"len(requests) = {len(requests)}" fetch_data_request = requests[0] else: raise ValueError(f"invalid browser name {browser_name}") diff --git a/tests/test_figure_resampler_selenium.py b/tests/test_figure_resampler_selenium.py index ccdf9573..115d68a3 100644 --- a/tests/test_figure_resampler_selenium.py +++ b/tests/test_figure_resampler_selenium.py @@ -625,7 +625,7 @@ def test_multi_trace_go_figure(driver, multi_trace_go_figure): n_updated_traces=30, ) - fr.drag_and_zoom("xy", x0=0.1, x1=0.3, y0=0.6, y1=0.9) + fr.drag_and_zoom("xy", x0=0.1, x1=0.3, y0=0.3, y1=0.5) fr.clear_requests(sleep_time_s=3) # First, apply some horizontal based zooms diff --git a/tests/test_figurewidget_resampler.py b/tests/test_figurewidget_resampler.py index 03f73bd4..ac341a33 100644 --- a/tests/test_figurewidget_resampler.py +++ b/tests/test_figurewidget_resampler.py @@ -142,6 +142,23 @@ def test_add_not_a_hf_trace(float_series): ) +def test_add_not_scatter(): + fw_fig = FigureWidgetResampler( + go.Figure(go.Bar(x=[1, 2, 3, 4], y=[1, 2, 3, 4])), verbose=True + ) + + # we do not want to have an relayout update + assert len(fw_fig._relayout_hist) == 0 + + # zoom in on both traces + fw_fig.layout.update( + {"xaxis": {"range": [0, 1]}}, + overwrite=False, + ) + # reset axes + fw_fig.reset_axes() + + def test_box_histogram(float_series): base_fig = make_subplots( rows=2,