Search code examples
pythongraphdrop-down-menuplotlyplotly.graph-objects

How to update axes when value on dropdown changes with go.Bar() (plotly)?


I trying to update the xaxis_title_text (update_layout) and the tickvals and ticktext (update_xaxes) when the dropdown value changes. I have tried to adapt the Plotly examples (link) and this answer, but I am stuck with the axes updates. In Figures 1 and 2, we can see from Figure 1 to Figure 2 that the axes do not update when the dropdown changes. Tkx for the help with that. enter image description here Figure 1 enter image description here Figure 2

CODE:

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

### My df has more than 1,5M rows with 79 columns. Each column may vary the scale of the number.
### E.g.: Age, weight, income, etc aren't normalized.
df = pd.DataFrame() # any dataframe to compute a histogram
num_cols = df.columns

def compute_bins(x, bins, return_var):
   hist, bins_edges = np.histogram(x, bins=bins)
   bins_text = [f"({np.round(bins_edges[i],2)}, {np.round(bins_edges[i+1],2)}]" for i in range(len(bins_edges)-1) ]

   if return_var == 'h':
      return hist
   else:
      return bins_text

hist = compute_bins(x=df[x_title].values, bins=10, return_var='h')
hist = compute_bins(x=df[x_title].values, bins=10, return_var='b')

fig = go.Figure(go.Bar(x=np.array(range(len(bins_text))), y=hist))

my_buttons = [dict(
                   mehotd='update',
                   args=[{"y": [ compute_bins(x=df[x_title].values, bins=10, return_var='h'), 'underfined' ]
                          "x": [ compute_bins(x=df[x_title].values, bins=10, return_var='h'), 'underfined' ]}
                        ],
                   label = c
                  ) for k, c in enumerate(num_cols)]

fig.update_axes(tickvals==np.array(range(len(bins_text))), ticktext=bins_text)
fig.update_layout(bargap=0, xaxis_title_text=x_title, yaxis_title_text='Count',
                  updatemenus=[dict(
                                   active=0,
                                   x=0,y=1.2,
                                   xanchor='left',
                                   yanchor='top',
                                   buttons=my_buttons
                              )]
                  )


Solution

  • As input values for the drop-down, settings related to fig.data and fig.layout are required. I have modified your code using iris sample data since you did not present any data.

    import pandas as pd
    import numpy as np
    import plotly.graph_objects as go
    import plotly.express as px
    
    df = px.data.tips()
    num_cols = df.columns[:2]
    
    x_title = 'total_bill'
    
    def compute_bins(x, bins, return_var):
       hist, bins_edges = np.histogram(x, bins=bins)
       bins_text = [f"({np.round(bins_edges[i],2)}, {np.round(bins_edges[i+1],2)}]" for i in range(len(bins_edges)-1) ]
    
       if return_var == 'h':
          return hist
       else:
          return bins_text
    
    hist = compute_bins(x=df[x_title].values, bins=10, return_var='h')
    bins_text = compute_bins(x=df[x_title].values, bins=10, return_var='b')
        
    fig = go.Figure(go.Bar(x=bins_text, y=hist))
    
    my_buttons = [dict(
                       method='update',
                       args=[{"y": [compute_bins(x=df[c].values, bins=10, return_var='h')],
                              "x": [compute_bins(x=df[c].values, bins=10, return_var='b')]},
                             {'xaxis': {'ticktext':[compute_bins(x=df[c].values, bins=10, return_var='b')],
                              'title': c}}
                            ],
                       label = c
                      ) for k, c in enumerate(num_cols)]
    
    fig.update_xaxes(tickvals=np.array(range(len(bins_text))), ticktext=bins_text)
    fig.update_layout(bargap=0, xaxis_title_text=x_title, yaxis_title_text='Count',
                      updatemenus=[dict(
                                       active=0,
                                       x=0,y=1.2,
                                       xanchor='left',
                                       yanchor='top',
                                       buttons=my_buttons
                                  )]
                      )
    fig.show()
    

    enter image description here

    enter image description here