Comments (9)
Hi @Joakimden4,
Can you verify whether the functionality (and demo posted on #286 resolves your issue)?
from plotly-resampler.
Hi @jonasvdd,
The provided example works when it is not combined with dash components.
However, when I wrap the figure in a dcc.Graph component and display it in a dash, it behaves the exact same way as originally reported in this bug.
Am I implementing it wrongly within the dash framework?
I ran this code on the bug/rangeselector branch using the dependencies specified by you:
import dash
from dash import html, dcc
from plotly_resampler import register_plotly_resampler
import plotly.graph_objects as go
import pandas as pd
register_plotly_resampler(mode="figure", create_overview=True, verbose=True)
df_hourly = pd.read_csv("data.csv", index_col=0)
hourly_fig = go.Figure(
layout=dict(
dragmode='pan',
hovermode='x unified',
xaxis=dict(
rangeslider_visible=True,
rangeselector=dict(
buttons=list([
dict(count=1, label="1 day", step="day", stepmode="backward"),
dict(count=1, label="1 month", step="month", stepmode="backward"),
dict(count=1, label="1 year", step="year", stepmode="backward"),
dict(step="all")
])
),
),
),
)
hourly_fig.add_trace(go.Scattergl(x=df_hourly['Date'], y=df_hourly['MWh'], name='Hourly position', mode='lines'))
app = dash.Dash(__name__, meta_tags=[{'name':'viewport', 'content':'width=device-width, initial-scale=1.0'}])
app.layout = html.Div(
dcc.Graph(
id='graph_bo_hourly',
figure=hourly_fig
)
)
app.run(debug=False, host='localhost')
from plotly-resampler.
Hi @Joakimden4,
When you use plotly-resampler from the main-branch, the dash app example below appears to work:
What did I change / how did I make this:
- You cannot use
register_plotly_resampler
within dash apps, the function is mainly intended for usage within notebook environments - I copied a large part of the code from the
xaxis overview
dash app folder / xaxis overview file
import dash
from dash import html, dcc, Input, Output, State, no_update
import plotly.graph_objects as go
import pandas as pd
# For plain dash apps you need to use the FigureResampler class
# (the register function is for notebooks only)
from plotly_resampler import FigureResampler, ASSETS_FOLDER
FigureResampler(create_overview=True, verbose=True)
GRAPH_ID = "graph-id"
OVERVIEW_GRAPH_ID = "overview-graph"
# 0. Load the data
df_hourly = pd.read_csv("data.csv", index_col=0)
# 1. Create the figure and add data
# fmt: off
hourly_fig = FigureResampler(
go.Figure(
layout=dict(
dragmode="pan",
hovermode="x unified",
xaxis=dict(
rangeselector=dict(
buttons=list( [
dict(count=1, label="1 day", step="day", stepmode="backward"),
dict(count=1, label="1 month", step="month", stepmode="backward"),
dict(count=1, label="1 year", step="year", stepmode="backward",),
])
),
),
)
),
)
hourly_fig.add_trace(go.Scattergl(x=df_hourly["Date"], y=df_hourly["MWh"], name="Hourly position", mode="lines"))
# 1.1 Create the overview figure
coarse_fig = hourly_fig._create_overview_figure()
# Create the app in which the figure will be displayed
app = dash.Dash(
__name__,
meta_tags=[
{"name": "viewport", "content": "width=device-width, initial-scale=1.0"}
],
assets_folder=ASSETS_FOLDER,
external_scripts=["https://cdn.jsdelivr.net/npm/lodash/lodash.min.js"],
)
# NOTE: you need to create both a coars and
app.layout = html.Div(
children=[
dcc.Graph(id=GRAPH_ID, figure=hourly_fig),
dcc.Graph(id=OVERVIEW_GRAPH_ID, figure=coarse_fig),
]
)
# -------------------- Callbacks --------------------
# --- Clientside callbacks used to bidirectionally link the overview and main graph ---
app.clientside_callback(
dash.ClientsideFunction(namespace="clientside", function_name="main_to_coarse"),
dash.Output(OVERVIEW_GRAPH_ID, "id", allow_duplicate=True),
dash.Input(GRAPH_ID, "relayoutData"),
[dash.State(OVERVIEW_GRAPH_ID, "id"), dash.State(GRAPH_ID, "id")],
prevent_initial_call=True,
)
app.clientside_callback(
dash.ClientsideFunction(namespace="clientside", function_name="coarse_to_main"),
dash.Output(GRAPH_ID, "id", allow_duplicate=True),
dash.Input(OVERVIEW_GRAPH_ID, "selectedData"),
[dash.State(GRAPH_ID, "id"), dash.State(OVERVIEW_GRAPH_ID, "id")],
prevent_initial_call=True,
)
# --- FigureResampler update callback ---
# The plotly-resampler callback to update the graph after a relayout event (= zoom/pan)
# As we use the figure again as output, we need to set: allow_duplicate=True
@app.callback(
Output(GRAPH_ID, "figure", allow_duplicate=True),
Input(GRAPH_ID, "relayoutData"),
prevent_initial_call=True,
)
def update_fig(relayoutdata: dict):
if relayoutdata is None:
return no_update
return hourly_fig.construct_update_data_patch(relayoutdata)
# Start the app
app.run(debug=False, host="localhost")
I hope this helps you further.
Kind regards,
Jonas
from plotly-resampler.
Hi @jonasvdd,
Thank you very much for the provided example.
I'd love to try this out in my actual project that uses plotly-resampler as dependency.
When are you planning on releasing this?
from plotly-resampler.
Hi @Joakimden4,
I plan to release a new version somewhere this week.
( I just want to improve the docs of the register_plotly_resampler
function)
Kind regards,
Jonas
from plotly-resampler.
Hi @jonasvdd,
That's awesome, thanks a lot for your hard work! :)
from plotly-resampler.
Version 0.9.2 was released!
Please let me know whether your code works, and if so, you can close this issue! :)
from plotly-resampler.
Hi @jonasvdd,
I've updated to version 0.9.2, but I'm still not able to get it to work.
The issue is that no matter what I try to pass to the construct_update_data_patch
method, it returns a dash.no_update event.
It always executes line 1333 of figure_resampler_interface.py.
My use case is to pass the figure attribute of the dcc.Graph element through a callback and then apply the resampling.
The reason for this is that the user can change the data for the figure during runtime of the application, so I cannot set a static figure. However, even if I try rebuilding the figure from scratch within the callback to avoid potential dash callback passing format issues, I still end up with the dash.no_update event.
I've tried with a super simple use case where there is no coarse graph.
If you have any ideas how to solve this it would be much appreciated!
@callback(
Output('graph_bo_hourly', 'figure', allow_duplicate=True),
Input('graph_bo_hourly', 'relayoutData'),
State('graph_bo_hourly', 'figure'),
prevent_initial_call=True
)
def resample_fig(relayoutdata, fig_state):
if relayoutdata is None:
return dash.no_update
else:
hourly_fig = FigureResampler(
go.Figure(
layout=dict(
dragmode='pan',
hovermode='x unified',
xaxis=dict(
rangeselector=dict(
buttons=list([
dict(count=1, label="1 day", step="day", stepmode="backward"),
dict(count=1, label="1 month", step="month", stepmode="backward"),
dict(count=1, label="1 year", step="year", stepmode="backward"),
])
),
),
),
)
)
x_dates = [datetime.strptime(date, "%Y-%m-%dT%H:%M:%S") for date in fig_state['data'][0]['x']]
hourly_fig.add_trace(go.Scattergl(x=x_dates, y=fig_state['data'][0]['y'], name='Hourly position', mode='lines'))
return hourly_fig.construct_update_data_patch(relayoutdata)
from plotly-resampler.
Hi @jonasvdd,
I just realized that I'm continually trying to resample the downsampled dataset, which explains why it's not working.
I will have to rethink my whole approach.
I'll let you know when I've verified whether it's working, once I've fixed my approach.
from plotly-resampler.
Related Issues (20)
- whl install issue in kaggle HOT 1
- [BUG] Hover data does not match the displayed resampled point in scatter plot HOT 1
- [BUG] TraceUpdater fails to update graphs in Tabs after switching tab HOT 8
- Python 3.12 support HOT 4
- [FEAT] improve documentation of the aggregators HOT 1
- Feature Request: Support polars and/or DataFrame api
- [FEAT] Support panel dashboarding library HOT 7
- construct_update_data function returns no_update value HOT 1
- [FEAT] Support OHLC Traces HOT 2
- [BUG] spikes are removed when clicking on reset axis
- [BUG] Legend does not display when trace has no real data points HOT 4
- [Request] Make dash dependency optional
- [BUG] error proc_macro_span_shrink during pip installation HOT 2
- [FEAT] Support Numpy float 16 HOT 3
- [BUG] Using gunicorn to deploy a dash app with plotly-resampler in Linux HOT 7
- [BUG] nan-handling for `M4` aggregator not yet available
- [BUG] `renderer="png"` - rendering png images in notebooks - does not work HOT 6
- [BUG] Lines become broken when zoomed in HOT 2
- [BUG] Error handling timezones HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from plotly-resampler.