'update_layout' not working after a few clicks

I have a dropdown menu where I can choose the x- and y-axis variables for a scatter plot. Moreover, a categorical variable can be selected in the menu indicating how to color the points. This seems to work for a few clicks, but then I am getting β€˜%{customdata[0]}’ in the hover box, and the plot is not correct. I am using plotly 5.9.0. To be able to select the categorical variable for the coloring, I used traces. Below is a reproducible example. I would be grateful for any help.

import pandas as pd
import numpy as np
import plotly.express as px
import plotly.graph_objects as go

X = pd.DataFrame({  'num1': [1,2,3,4],
                    'num2': [40,30,20,10],
                    'num3': [0,1,2,3],
                    'cat1': ['A', 'A', 'A', 'B'],
                    'cat2': ['c', 's', 's', 's'],
                    'cat3': ['a', 'b', 'c', 'd']})

numerical_features   = sorted(X.select_dtypes(include=np.number).columns.tolist())
categorical_features = sorted(list(set(X.columns) - set(numerical_features)))

feature_1 = numerical_features[0]
feature_2 = numerical_features[1]

fig = go.Figure()

for categorical_feature_id in range(len(categorical_features)):

    fig.add_traces(list(px.scatter(X, x=feature_1, y=feature_2, color=categorical_features[categorical_feature_id],
                                         labels={feature_1:feature_1, feature_2:feature_2},
                                         hover_data=['cat3', 'num3']).select_traces()))

fig.update_layout(
        xaxis_title=feature_1,
        yaxis_title=feature_2,
        updatemenus=[
            {
                "buttons": [
                    {
                        "label": f"x - {x}",
                        "method": "update",
                        "args": [
                            {"x": [X[x]]},
                            {"xaxis": {"title": x}},
                        ],
                    }
                    for x in numerical_features
                ]
            },
            {
                "buttons": [
                    {
                        "label": f"y - {y}",
                        "method": "update",
                        "args": [
                            {"y": [X[y]]},
                            {"yaxis": {"title": y}}
                        ],
                    }
                    for y in numerical_features
                ],
                "y": 0.8,
            },
            {
                "buttons": [
                    {
                        "label": f"z - {categorical_features[categorical_feature_id]}",
                        "method": "update",
                        "args": [{'visible':    [False if (i<categorical_feature_id) or (i>categorical_feature_id) else True for i in range(len(categorical_features))]},
                                 {'showlegend': [False if (i<categorical_feature_id) or (i>categorical_feature_id) else True for i in range(len(categorical_features))]}]
                    }
                    for categorical_feature_id in range(len(categorical_features))
                ],
                "y": 0.6,
            }])
fig.show()

Maybe I should have mentioned that I am using plotly in jupyterlab3.

An example of how the figure looks after a few updates:

I have posted this problem on SO, and there is a solution:

It works, but it is not perfect. I am a bit concerned with speed. In an actual case application, I have 1700 observations (1700 points in the scatter plot, so not a huge dataset) and 8 categorical variables, and the plot is a bit sluggish. I tested replacing go.Scatter with go.Scattergl , and the speed greatly improved. However, it causes other problems. go.Scatter is in two loops. If I replace it with go.Scattergl in both loops (or in the 2nd loop), hover information from the hovertemplate disappears. If I replace it in the first loop only, speed seems fine and hovertemplate works, but the coloring of the points does not work - all points have one color, even though the hover boxes have different/correct colors.

Another problem, albeit small, is that in the legend, it is impossible to properly unclick/click the items. Normally, this way the respective points in the scatter plot would disappear/appear. This is because now the legend is made from dummy entries.

hi @wo222
Thank you for sharing a link to the solution with us. I will let my colleagues know of this challenge.

1 Like