Search code examples
pythonbuttonplotlyhistogram

How to update histogram nbins with buttons in plotly (python)?


I am having trouble updating the number of bins when updating the plot with buttons. This is an examplary short dataframe. In the full version, there are a lot more rows so there is a point in using the initial nbins = 100. However, I would like to change the number of bins for each column when updating the histogram.

dataset = pd.DataFrame(
    {'age': [19, 18, 28, 33, 32],
    'bmi': [27.9, 33.77, 33.0, 22.705, 28.88],
    'children': [0, 1, 3, 0, 0]}
)

fig = px.histogram(x = dataset['age'], nbins = 100)
fig.update_layout(xaxis_title = 'age')

buttons = []
for column in dataset.columns:
    buttons.append(
        dict(
            args = [
                {'x': [dataset[column]]},
                {'xaxis.title': column},
                
                # __________________________________
                # I TRIED THIS since fig.layout.figure.data[0].nbinsx = 100
                # {'figure.data[0].nbinsx': 5}
                # __________________________________

            ],
            label = column,
            method = 'update',
        )
    )

fig.update_layout(
    updatemenus = [
        dict(type = 'buttons', buttons = buttons,
             direction = 'right', x=1, y=1.15)
    ],
    title_text = 'Histograms'
)
fig.show()

This is how the histogram looks with the button options available.

**When I change the column that the histogram is constructed for, the number of bins do not change. How do I fix this? I tried to **

THIS IS THE IMAGE OF THE HISTOGRAM! I HAVE YET TO EARN REPUTATION POINTS FOR IMAGE EMBEDDING TO BE POSSIBLE.

enter image description here


Solution

    • you have not defined number of bins you want per column. Have used col_bins = {c: int(dataset[c].max()-dataset[c].min()) for c in dataset.columns} to generate values from your data
    • from a style perspective I use list and dict comprehensions to build updatemenus structures
    • your code is close, key part is understanding args of update method. It's a list where first element is dict to update traces and second element is a dict to update layout. There are two updates to traces: x and nbinsx so they are including in one dict
    import pandas as pd
    import plotly.express as px
    
    dataset = pd.DataFrame(
        {
            "age": [19, 18, 28, 33, 32],
            "bmi": [27.9, 33.77, 33.0, 22.705, 28.88],
            "children": [0, 1, 3, 0, 0],
        }
    )
    col_bins = {c: int(dataset[c].max()-dataset[c].min()) for c in dataset.columns}
    
    fig = px.histogram(x=dataset["age"], nbins=100)
    fig.update_layout(
        updatemenus=[
            {
                "buttons": [
                    {
                        "label": c,
                        "method": "update",
                        "args": [{"x": [dataset[c]], "nbinsx":bins}, {"xaxis.title":c}],
                    }
                    for c, bins in col_bins.items()
                ],
                "direction": "right",
                "type":"buttons",
                "x":1,
                "y":1.15
            }
        ],
        xaxis_title="age",
        title_text = 'Histograms'
    )