Skip to content

Commit 2b79498

Browse files
jonasvddjvdd
andauthored
Bug/pop rangeselector (#279)
* 🐐 related to issue #275 * 💨 small fixes * 💪 update readme fix #276 * 💨 * 🖊️ update readme * ✏️ * 🧹 formatting * 🖍️ adding docs * 🙈 remove duplicate entry from gitignore --------- Co-authored-by: Jeroen Van Der Donckt <[email protected]> Co-authored-by: Jeroen Van Der Donckt <[email protected]>
1 parent cc07774 commit 2b79498

File tree

4 files changed

+33
-17
lines changed

4 files changed

+33
-17
lines changed

.gitignore

+8-2
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@ venv*
22
.cache_datasets/
33
*.ruff*
44
*.DS_Store
5-
file_system_store/
6-
file_system_backend/
75

86
# Sphinx documentation
97
*_build/
@@ -157,3 +155,11 @@ cython_debug/
157155
# sphinx-docs
158156
sphinx/_build
159157
sphinx/_autosummary
158+
159+
# dash apps
160+
file_system_backend/
161+
file_system_store/
162+
163+
164+
# testing
165+
bugs/

README.md

+15-15
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,13 @@
1313
[![Testing](https://github.com/predict-idlab/plotly-resampler/actions/workflows/test.yml/badge.svg)](https://github.com/predict-idlab/plotly-resampler/actions/workflows/test.yml)
1414
[![Documentation](https://img.shields.io/badge/read%20our%20docs!-informational)](https://predict-idlab.github.io/plotly-resampler/latest)
1515

16-
17-
1816
<!-- [![Downloads](https://pepy.tech/badge/plotly-resampler)](https://pepy.tech/project/plotly-resampler) -->
1917

2018
> `plotly_resampler`: visualize large sequential data by **adding resampling functionality to Plotly figures**
2119
22-
[Plotly](https://github.com/plotly/plotly.py) is an awesome interactive visualization library, however it can get pretty slow when a lot of data points are visualized (100 000+ datapoints). This library solves this by downsampling (aggregating) the data respective to the view and then plotting the aggregated points. When you interact with the plot (panning, zooming, ...), callbacks are used to aggregate data and update the figure.
20+
`plotly-resampler` improves the scalability of [Plotly](https://github.com/plotly/plotly.py) for visualizing large time series datasets. Specifically, our library _dynamically_ **aggregates time-series data respective to the current graph view**, ensuring efficient and responsive updates during user interactions like panning or zooming via callbacks.
21+
22+
This core aggregation functionality is achieved by utilizing by _time-series data point selection algorithms_, for which `plotly-resampler` leverages the highly optimized implementations available in [tsdownsample](https://github.com/predict-idlab/tsdownsample). Our default data aggregation method is `MinMaxLTTB` (and selects 1000 data points for plotting). For a deeper understanding of this method, you can consult to the algorithm's dedicated [MinMaxLTTB repository](https://github.com/predict-idlab/MinMaxLTTB) and the associated [research paper](https://arxiv.org/abs/2305.00332).
2323

2424
![basic example gif](https://raw.githubusercontent.com/predict-idlab/plotly-resampler/main/mkdocs/static/basic_example.gif)
2525

@@ -34,32 +34,31 @@ In [this Plotly-Resampler demo](https://github.com/predict-idlab/plotly-resample
3434
<!-- - [Documentation]() work in progress 🚧 -->
3535
<!-- - [Example notebooks](https://github.com/predict-idlab/plotly-resampler/tree/main/examples/) -->
3636

37-
### Installation
37+
### 🛠️ Installation
3838

3939
| [**pip**](https://pypi.org/project/plotly_resampler/) | `pip install plotly-resampler` |
4040
| ---| ----|
4141
<!-- | [**conda**](https://anaconda.org/conda-forge/plotly_resampler/) | `conda install -c conda-forge plotly_resampler` | -->
4242

4343
<br>
44-
<details><summary><b>What is the difference between plotly-resampler figures and plain plotly figures?</b></summary>
44+
<details><summary><b>👀 What is the difference between plotly-resampler figures and plain plotly figures?</b></summary>
4545

4646
`plotly-resampler` can be thought of as wrapper around plain plotly figures which adds visualization scalability to line-charts by dynamically aggregating the data w.r.t. the front-end view. `plotly-resampler` thus adds dynamic aggregation functionality to plain plotly figures.
4747

48-
**Important to know**:
48+
**Important to know**:
4949

50-
* ``show`` *always* returns a static html view of the figure, i.e., no dynamic aggregation can be performed on that view.
50+
* ``show`` *always* generates a static HTML view of the figure, prohibiting dynamic aggregation.
5151
* To have dynamic aggregation:
52-
53-
* with ``FigureResampler``, you need to call ``show_dash`` (or output the object in a cell via ``IPython.display``) -> which spawns a dash-web app, and the dynamic aggregation is realized with dash callback.
54-
* with ``FigureWidgetResampler``, you need to use ``IPython.display`` on the object, which uses widget-events to realize dynamic aggregation (via the running IPython kernel).
52+
* Use `show_dash` with `FigureResampler` to initiate a **Dash** app to realize the dynamic aggregation with **callbacks**.<br>(or output the object in a cell via ``IPython.display``), which will also spawn a dash-web app
53+
* with ``FigureWidgetResampler``, you need to use ``IPython.display`` on the object, which uses widget-events to realize dynamic aggregation (via the running **IPython kernel**).
5554

5655
**Other changes of plotly-resampler figures w.r.t. vanilla plotly**:
5756

5857
* **double-clicking** within a line-chart area **does not Reset Axes**, as it results in an “Autoscale” event. We decided to implement an Autoscale event as updating your y-range such that it shows all the data that is in your x-range.
5958
* **Note**: vanilla Plotly figures their Autoscale result in Reset Axes behavior, in our opinion this did not make a lot of sense. It is therefore that we have overriden this behavior in plotly-resampler.
6059
</details><br>
6160

62-
### Features :tada:
61+
### 📋 Features
6362

6463
* **Convenient** to use:
6564
* just add either
@@ -72,7 +71,7 @@ In [this Plotly-Resampler demo](https://github.com/predict-idlab/plotly-resample
7271
* Interface for **various aggregation algorithms**:
7372
* ability to develop or select your preferred sequence aggregation method
7473

75-
## Usage
74+
## 🚀 Usage
7675

7776
**Add dynamic aggregation** to your plotly Figure _(unfold your fitting use case)_
7877
* 🤖 <b>Automatically</b> _(minimal code overhead)_:
@@ -149,9 +148,9 @@ In [this Plotly-Resampler demo](https://github.com/predict-idlab/plotly-resample
149148

150149
> **Note**:
151150
> Any plotly Figure can be wrapped with `FigureResampler` and `FigureWidgetResampler`! 🎉
152-
> But, (obviously) only the scatter traces will be resampled.
151+
> But **only** the `go.Scatter`/`go.Scattergl` **traces are resampled**.
153152

154-
## Important considerations & tips
153+
## 💭 Important considerations & tips
155154

156155
* When running the code on a server, you should forward the port of the `FigureResampler.show_dash()` method to your local machine.<br>
157156
**Note** that you can add dynamic aggregation to plotly figures with the `FigureWidgetResampler` wrapper without needing to forward a port!
@@ -160,9 +159,10 @@ In [this Plotly-Resampler demo](https://github.com/predict-idlab/plotly-resample
160159
The <b style="color:orange">[R]</b> in the legend indicates when the corresponding trace is being resampled (and thus possibly distorted) or not. Additionally, the `~<range>` suffix represent the mean aggregation bin size in terms of the sequence index.
161160
* The plotly **autoscale** event (triggered by the autoscale button or a double-click within the graph), **does not reset the axes but autoscales the current graph-view** of plotly-resampler figures. This design choice was made as it seemed more intuitive for the developers to support this behavior with double-click than the default axes-reset behavior. The graph axes can ofcourse be resetted by using the `reset_axis` button. If you want to give feedback and discuss this further with the developers, see issue [#49](https://github.com/predict-idlab/plotly-resampler/issues/49).
162161

163-
## Citation and papers
162+
## 📜 Citation and papers
164163

165164
The paper about the plotly-resampler toolkit itself (preprint): https://arxiv.org/abs/2206.08703
165+
166166
```bibtex
167167
@inproceedings{van2022plotly,
168168
title={Plotly-resampler: Effective visual analytics for large time series},

plotly_resampler/figure_resampler/figure_resampler.py

+7
Original file line numberDiff line numberDiff line change
@@ -402,6 +402,13 @@ def _create_overview_figure(self) -> go.Figure:
402402
coarse_fig._grid_ref = reduced_fig._grid_ref
403403
coarse_fig._data_validator.set_uid = False
404404
coarse_fig.add_traces(coarse_fig_dict["data"])
405+
# remove any update menus for the coarse figure
406+
coarse_fig.layout.pop("updatemenus", None)
407+
# remove the `rangeselector` options for all 'axis' keys in the layout of the
408+
# coarse figure
409+
for k, v in coarse_fig.layout._props.items():
410+
if "axis" in k:
411+
v.pop("rangeselector", None)
405412

406413
# height of the overview scales with the height of the dynamic view
407414
coarse_fig.update_layout(

plotly_resampler/figure_resampler/figure_resampler_interface.py

+3
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import numpy as np
2121
import pandas as pd
2222
import plotly.graph_objects as go
23+
from pandas.io.json._normalize import nested_to_record
2324
from plotly.basedatatypes import BaseFigure, BaseTraceType
2425

2526
from ..aggregation import AbstractAggregator, MedDiffGapHandler, MinMaxLTTB
@@ -1369,6 +1370,8 @@ def _construct_update_data(
13691370
current_graph = self._get_current_graph()
13701371
updated_trace_indices, cl_k = [], []
13711372
if relayout_data:
1373+
# flatten the possibly nested dict using '.' as separator
1374+
relayout_data = nested_to_record(relayout_data, sep=".")
13721375
self._print("-" * 100 + "\n", "changed layout", relayout_data)
13731376

13741377
cl_k = list(relayout_data.keys())

0 commit comments

Comments
 (0)