title: Plotly: Scatter plot with dropdown menu to change data and calculated annotation
body: <p>I'm trying to make a scatter plot with 2 dropdown menus that select a data column (from a pandas data frame) to be plotted for x and y-axis. I also want the plot to have a correlation stats annotation that change with the dropdown selection, because the annotation is calculated on both the x and y data as parameters. The first part I've managed to do with the code example below, but I am struggling with the annotation.</p>
  <pre class="lang-py prettyprint-override"><code>import pandas as pd
  import numpy as np
  import plotly.graph_objects as go
  
  # Prep random data
  data = pd.DataFrame(dict(
      A=np.random.randint(11, size=10),
      B=np.random.randint(11, size=10),
      C=np.random.randint(11, size=10),
      D=np.random.randint(11, size=10) 
  ))
  
  # Create figure and add one scatter trace
  fig = go.Figure()
  
  fig.add_trace(go.Scatter(
      x=data['A'], 
      y=data['A'],
      visible=True,
      mode='markers',
      )
                )
  
  # Create x and y buttons
  x_buttons = []
  y_buttons = []
  
  for column in data.columns:
      x_buttons.append(dict(method='restyle',
                          label=column,
                          args=[{'x': [data[column]]}]
                          )
                  )
      
      y_buttons.append(dict(method='restyle',
                          label=column,
                          args=[{'y': [data[column]]}]
                          )
                  )
  
  # Pass buttons to the updatemenus argument
  fig.update_layout(updatemenus=[dict(buttons=x_buttons, direction='up', x=0.5, y=-0.1),
                                 dict(buttons=y_buttons, direction='right', x=-0.01, y=0.5)])
  </code></pre>
  <p>My idea was to first define a function that will take the x and y attributes from the <a href="https://plotly.com/python/figure-structure/" rel="nofollow noreferrer">figure data structure</a> (hoping that the dropdown selection change this attributes) and returns the text annotation. Then, based on the <a href="https://plotly.com/python/dropdowns/#update-dropdown" rel="nofollow noreferrer">plotly reference example</a>, add the annotation to <code>args</code> and change the method of the buttons to 'update'. However, that doesn't seem to be the case and the annotation is static. Anyone has an idea of how I could achieve this? Here is the function and the final code:</p>
  <pre class="lang-py prettyprint-override"><code>from scipy import stats
  
  def corr_annotation(x, y):
      pearsonr = stats.pearsonr(x, y)
      return 'r = {:.2f} (p = {:.3f})'.format(pearsonr[0], pearsonr[1])
  </code></pre>
  <pre class="lang-py prettyprint-override"><code>import pandas as pd
  import numpy as np
  import plotly.graph_objects as go
  
  # Prep random data
  data = pd.DataFrame(dict(
      A=np.random.randint(11, size=10),
      B=np.random.randint(11, size=10),
      C=np.random.randint(11, size=10),
      D=np.random.randint(11, size=10) 
  ))
  
  # Create figure and add one scatter trace
  fig = go.Figure()
  
  fig.add_trace(go.Scatter(
      x=data['A'], 
      y=data['A'],
      visible=True,
      mode='markers',
      )
                )
  
  fig.add_annotation(dict(text=corr_annotation(fig['data'][0]['x'], fig['data'][0]['y']),
                          showarrow=False, 
                          yref='paper', xref='paper',
                          x=0.99, y=0.95))
  
  # Create x and y buttons
  x_buttons = []
  y_buttons = []
  
  for column in data.columns:
      x_buttons.append(dict(method='update',
                          label=column,
                          args=[{'x': [data[column]]},
                                {'annotations': [dict(text=corr_annotation(fig['data'][0]['x'], fig['data'][0]['y']),
                                                      showarrow=False, 
                                                      yref='paper', xref='paper',
                                                      x=0.99, y=0.95)]}]
                          )
                  )
      
      y_buttons.append(dict(method='update',
                          label=column,
                          args=[{'y': [data[column]]},
                                {'annotations': [dict(text=corr_annotation(fig['data'][0]['x'], fig['data'][0]['y']),
                                                      showarrow=False, 
                                                      yref='paper', xref='paper',
                                                      x=0.99, y=0.95)]}]
                          )
                  )
  
  # Pass buttons to the updatemenus argument
  fig.update_layout(updatemenus=[dict(buttons=x_buttons, direction='up', x=0.5, y=-0.1),
                                 dict(buttons=y_buttons, direction='right', x=-0.01, y=0.5)])
  </code></pre>
  <p><a href="https://i.stack.imgur.com/F2S9l.png" rel="nofollow noreferrer">And the final result</a></p>