Skip to content

[BUG] Candlestick chart is not cleared properly when updated with callback  #5316

Closed
@vemikhaylov

Description

@vemikhaylov

Describe your context
Please provide us your environment so we can easily reproduce the issue.

  • replace the result of pip list | grep dash below
dash                 1.17.0
dash-core-components 1.13.0
dash-html-components 1.1.1
dash-renderer        1.8.3
dash-table           4.11.0
  • if frontend related, tell us your Browser, Version and OS

    • OS: macOS Mojave 10.14.5
    • Browser: Safari (12.1.1); Chrome (87.0.4280.88)

Describe the bug

During updating with callback Candlestick charts for different time intervals (e.g. 1 minutes, 10 minutes, 1 hour), selected with radio button, the previous traces are not cleared. The same thing works as expected for the Ohlc chart type.

from datetime import datetime

import dash
import dash_core_components as dcc
import dash_html_components as html
import pandas as pd
import plotly.graph_objs as go
from dash.dependencies import Input, Output

GRAPH_ID = "example-graph"
AGGREGATION_RADIOITEMS_ID = "aggregation-radioitems"

AGGREGATION_1M = "1min"
AGGREGATION_10M = "10min"
AGGREGATION_1H = "1H"


def main() -> None:
    app = _build_app()
    app.run_server()


def _build_app() -> dash.Dash:
    app = dash.Dash(__name__)
    app.layout = _build_layout()
    _register_callbacks(app)

    return app


def _register_callbacks(app: dash.Dash) -> None:
    app.callback(Output(GRAPH_ID, "figure"), [Input(AGGREGATION_RADIOITEMS_ID, "value")])(_build_figure_callback)


def _build_figure_callback(aggregation: str) -> go.Figure:
    df = _get_data()
    df = _aggregate_data(df, aggregation)
    candlestick_chart = _build_candlestick_chart(df)
    figure = go.Figure(data=[candlestick_chart])

    return figure


def _build_layout() -> html.Div:
    return html.Div(
        [dcc.Graph(id=GRAPH_ID, responsive=True, style={"height": "65vh"}), _build_aggregation_radioitems()]
    )


def _build_candlestick_chart(df: pd.DataFrame) -> go.Candlestick:
    return go.Candlestick(x=df.datetime, open=df.open, close=df.close, low=df.low, high=df.high)


def _build_aggregation_radioitems() -> dcc.RadioItems:
    return dcc.RadioItems(
        id=AGGREGATION_RADIOITEMS_ID,
        options=[
            {"label": "1min", "value": AGGREGATION_1M},
            {"label": "10min", "value": AGGREGATION_10M},
            {"label": "1h", "value": AGGREGATION_1H},
        ],
        value=AGGREGATION_1M,
    )


def _get_data() -> pd.DataFrame:
    return pd.DataFrame(
        [
            (datetime(2020, 12, 4, 0), 90.0, 110.0, 80.0, 120.0),
            (datetime(2020, 12, 4, 1), 91.0, 111.0, 81.0, 121.0),
            (datetime(2020, 12, 4, 2), 92.0, 112.0, 82.0, 122.0),
            (datetime(2020, 12, 4, 3), 93.0, 113.0, 83.0, 123.0),
            (datetime(2020, 12, 4, 4), 94.0, 114.0, 84.0, 124.0),
        ],
        columns=(["datetime", "open", "close", "low", "high"]),
    )


def _aggregate_data(df: pd.DataFrame, aggregation: str) -> pd.DataFrame:
    if df.empty:
        return df
    groups = df.groupby(pd.Grouper(key="datetime", freq=aggregation))
    result_df = groups.agg({"open": "first", "close": "last", "high": "max", "low": "min"})
    result_df = result_df.reset_index()

    return result_df


if __name__ == "__main__":
    main()

Expected behavior

The graph is fully updated after the callback call.

Screenshots

candlestick_chart_not_cleared

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugsomething broken

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions