sondor
sondor

Reputation: 13

Using multiple sliders with Plotly Dashboard scatter plot 3D

I want to create three filters for my 3D scatter plot.

Based on what I read here: https://medium.com/left-join/building-a-plotly-dashboard-with-dynamic-sliders-in-python-f5cf84161dc5 and here: https://plotly.com/python/3d-scatter-plots/ I should put only the sliders and call them in @app.callback as a list with parameters.

I tried like this:

from dash import Dash, dcc, html, Input, Output
import plotly.express as px

app = Dash(__name__)

app.layout = html.Div([
    html.H4('Iris samples filtered by petal width'),
    dcc.Graph(id="3d-scatter-plot-x-graph"),
    html.P("Petal Width:"),
    dcc.RangeSlider(
        id='3d-scatter-plot-x-range-slider',
        min=0, max=2.5, step=0.1,
        marks={0: '0', 2.5: '2.5'},
        value=[0.5, 2]
    ),
    html.P("Sepal Length:"),
    dcc.RangeSlider(
        id='3d-scatter-plot-y-range-slider',
        min=0, max=2.5, step=0.1,
        marks={0: '0', 2.5: '2.5'},
        value=[0.5, 2]
    ),
    html.P("Sepal Width:"),
    dcc.RangeSlider(
        id='3d-scatter-plot-z-range-slider',
        min=0, max=5, step=0.1,
        marks={0: '0', 5: '5'},
        value=[0.5, 4.5]
    ),
])


@app.callback(
    Output("3d-scatter-plot-x-graph", "figure"),
    [Input("3d-scatter-plot-x-range-slider", "value"),
    Input("3d-scatter-plot-y-range-slider", "value"),
    Input("3d-scatter-plot-z-range-slider", "value")])
def update_bar_chart(slider_x, slider_y, slider_z):
    df = px.data.iris()  # replace with your own data source
    low_x, high_x = slider_x
    low_y, high_y = slider_y
    low_z, high_z = slider_z
    mask = (df.petal_width > low_x) & (df.petal_width < high_x) & (df.sepal_length > low_y) & (df.sepal_length < high_y)

    fig = px.scatter_3d(df[mask],
                        x='sepal_length', y='sepal_width', z='petal_width',
                        color="species", hover_data=['petal_width'])
    return fig


if __name__ == "__main__":
    app.run_server(debug=True)

But I got nothing (empty plot with sliders)

And I didn't got any errors.

Any idea what can I do?

Upvotes: 1

Views: 975

Answers (1)

Korte Alma
Korte Alma

Reputation: 168

As you can see in @Kat's comment, you have to change the ranges and as I see Sepal Width slider does not take any effect, you have to add it to the update function.

from dash import Dash, dcc, html, Input, Output
import plotly.express as px

app = Dash(__name__)

app.layout = html.Div([
    html.H4('Iris samples filtered by petal width'),
    dcc.Graph(id="3d-scatter-plot-x-graph"),
    html.P("Petal Width:"),
    dcc.RangeSlider(
        id='3d-scatter-plot-x-range-slider',
        min=0, max=2.5, step=0.1,
        marks={0: '0', 2.5: '2.5'},
        value=[0.5, 2]
    ),
    html.P("Sepal Length:"),
    dcc.RangeSlider(
        id='3d-scatter-plot-y-range-slider',
        min=4.3, max=7.9, step=0.1,
        marks={0: '0', 2.5: '2.5'},
        value=[4.3, 7.9]
    ),
    html.P("Sepal Width:"),
    dcc.RangeSlider(
        id='3d-scatter-plot-z-range-slider',
        min=2, max=4, step=0.1,
        marks={0: '0', 5: '5'},
        value=[1.5, 4]
    ),
])


@app.callback(
    Output("3d-scatter-plot-x-graph", "figure"),
    [Input("3d-scatter-plot-x-range-slider", "value"),
    Input("3d-scatter-plot-y-range-slider", "value"),
    Input("3d-scatter-plot-z-range-slider", "value")])
def update_bar_chart(slider_x, slider_y, slider_z):
    df = px.data.iris()  # replace with your own data source
    low_x, high_x = slider_x
    low_y, high_y = slider_y
    low_z, high_z = slider_z
    mask = (df.petal_width > low_x) & (df.petal_width < high_x) & (df.sepal_length > low_y) & (df.sepal_length < high_y) & (df.sepal_width > low_z) & (df.sepal_width < high_z)

    fig = px.scatter_3d(df[mask],
                        x='sepal_length', y='sepal_width', z='petal_width',
                        color="species", hover_data=['petal_width'])
    return fig


if __name__ == "__main__":
    app.run_server(debug=True)

Upvotes: 1

Related Questions