Code Monkey home page Code Monkey logo

Comments (9)

jonasvdd avatar jonasvdd commented on June 9, 2024

Hi @Joakimden4,

Can you verify whether the functionality (and demo posted on #286 resolves your issue)?

from plotly-resampler.

Joakimden4 avatar Joakimden4 commented on June 9, 2024

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.

jonasvdd avatar jonasvdd commented on June 9, 2024

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.

Joakimden4 avatar Joakimden4 commented on June 9, 2024

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.

jonasvdd avatar jonasvdd commented on June 9, 2024

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.

Joakimden4 avatar Joakimden4 commented on June 9, 2024

Hi @jonasvdd,

That's awesome, thanks a lot for your hard work! :)

from plotly-resampler.

jonasvdd avatar jonasvdd commented on June 9, 2024

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.

Joakimden4 avatar Joakimden4 commented on June 9, 2024

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.

Joakimden4 avatar Joakimden4 commented on June 9, 2024

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)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.