title: Plotly-Dash: Update a trace on a graph that doesn't have its own dropdown
body: <p>This question is basically an addendum to this previously asked question:</p>
  <p><a href="https://stackoverflow.com/questions/64107660/properly-setting-up-callbacks-for-dynamic-dropdowns-plotly-dash/64122576?noredirect=1#comment113393478_64122576">Properly setting up callbacks for dynamic dropdowns plotly dash</a></p>
  <p>Now, I want to add a second trace to my plots which would be on a secondary y-axis. The data for the plot on the secondary y-axis would come from a similarly structured dict and dataframe, with similar naming conventions as well. Here is what I have.</p>
  <pre><code>app = JupyterDash(external_stylesheets=[dbc.themes.SLATE])
  
  index1= [1,2,3,4]
  columns1 =['time', '2m_temp_prod' , 'total_precip_prod']
  
  index2= [1,2,3,4]
  columns2 = ['time', '2m_temp_area', 'total_precip_area']
  
  df_vals_prod = {'corn': pd.DataFrame(index=index1, columns = columns1,
                                  data= np.random.randn(len(index1),len(columns1))).cumsum(),
                  'soybeans' : pd.DataFrame(index=index1, columns = columns1,
                                       data= np.random.randn(len(index1),len(columns1))).cumsum()}
  
  df_vals_area= {'corn': pd.DataFrame(index=index2, columns = columns2,
                                  data= np.random.randn(len(index2),len(columns2))).cumsum(),
                 'soybeans' : pd.DataFrame(index=index2, columns = columns2,
                                       data= np.random.randn(len(index2),len(columns2))).cumsum()}
  
  
  # mimic data properties of your real world data
  df_vals_prod['corn']['time'] =   [Timestamp('2020-09-23 06:00:00'), Timestamp('2020-09-23 12:00:00'), 
                                    Timestamp('2020-09-23 18:00:00'), Timestamp('2020-09-24 00:00:00')]
  df_vals_prod['corn'].set_index('time', inplace = True)
  df_vals_prod['soybeans']['time'] =   [Timestamp('2020-09-23 06:00:00'), Timestamp('2020-09-23 12:00:00'),
                                        Timestamp('2020-09-23 18:00:00'), Timestamp('2020-09-24 00:00:00')]
  df_vals_prod['soybeans'].set_index('time', inplace = True)
  
  df_vals_area['corn']['time'] =   [Timestamp('2020-09-23 06:00:00'), Timestamp('2020-09-23 12:00:00'),
                                    Timestamp('2020-09-23 18:00:00'), Timestamp('2020-09-24 00:00:00')]
  df_vals_area['corn'].set_index('time', inplace = True)
  df_vals_area['soybeans']['time'] =   [Timestamp('2020-09-23 06:00:00'), Timestamp('2020-09-23 12:00:00'),
                                        Timestamp('2020-09-23 18:00:00'), Timestamp('2020-09-24 00:00:00')]
  df_vals_area['soybeans'].set_index('time', inplace = True)
  
  index3= [1,2,3,4]
  columns3 =['time', '2m_temp_24hdelta_prod' , 'total_precip_24hdelta_prod']
  
  index4= [1,2,3,4]
  columns4 = ['time', '2m_temp_24hdelta_area', 'total_precip_24hdelta_area']
  
  df_deltas_prod = {'corn': pd.DataFrame(index=index3, columns = columns3,
                                  data= np.random.randn(len(index3),len(columns3))).cumsum(),
                  'soybeans' : pd.DataFrame(index=index3, columns = columns3,
                                       data= np.random.randn(len(index3),len(columns3))).cumsum()}
  
  df_deltas_area= {'corn': pd.DataFrame(index=index4, columns = columns4,
                                  data= np.random.randn(len(index4),len(columns4))).cumsum(),
                 'soybeans' : pd.DataFrame(index=index4, columns = columns4,
                                       data= np.random.randn(len(index4),len(columns4))).cumsum()}
  
  # mimic data properties of your real world data
  df_deltas_prod['corn']['time'] =   [Timestamp('2020-09-23 06:00:00'), Timestamp('2020-09-23 12:00:00'), 
                                    Timestamp('2020-09-23 18:00:00'), Timestamp('2020-09-24 00:00:00')]
  df_deltas_prod['corn'].set_index('time', inplace = True)
  df_deltas_prod['soybeans']['time'] =   [Timestamp('2020-09-23 06:00:00'), Timestamp('2020-09-23 12:00:00'),
                                        Timestamp('2020-09-23 18:00:00'), Timestamp('2020-09-24 00:00:00')]
  df_deltas_prod['soybeans'].set_index('time', inplace = True)
  
  df_deltas_area['corn']['time'] =   [Timestamp('2020-09-23 06:00:00'), Timestamp('2020-09-23 12:00:00'),
                                    Timestamp('2020-09-23 18:00:00'), Timestamp('2020-09-24 00:00:00')]
  df_deltas_area['corn'].set_index('time', inplace = True)
  df_deltas_area['soybeans']['time'] =   [Timestamp('2020-09-23 06:00:00'), Timestamp('2020-09-23 12:00:00'),
                                        Timestamp('2020-09-23 18:00:00'), Timestamp('2020-09-24 00:00:00')]
  df_deltas_area['soybeans'].set_index('time', inplace = True)
  
  # weighting
  all_options = {
      'Production': list(df_vals_prod[list(df_vals_prod.keys())[0]].columns[1:]),
      'Area': list(df_vals_area[list(df_vals_prod.keys())[0]].columns[1:])
  }
  
  
  controls = dbc.Card(
      [    dbc.FormGroup(
              [
                  dbc.Label(&quot;Crop&quot;),
                  dcc.Dropdown(
                      id='crop_dd',
                      options=[{'label': k.title(), 'value': k} for k in list(df_vals_prod.keys())],
                      value=list(df_vals_prod.keys())[0],
                      clearable=False,
                  ),
              ]
          ),    
          
          
          
          dbc.FormGroup(
              [
                  dbc.Label(&quot;Weighting&quot;),
                  dcc.Dropdown(
                      id='weight_dd',
                      options=[{'label': k, 'value': k} for k in all_options.keys()],
                      value='Area',
                      clearable=False,
                  ),
              ]
          ),
          dbc.FormGroup(
              [
                  dbc.Label(&quot;Forecast Variable&quot;),
                  dcc.Dropdown(
                      id='columns_dd',
                      clearable=False,
                  ),
              ]
          ),
  
      ],
      body=True,
  )
  
  
  app.layout = dbc.Container(
      [
          html.Hr(),
          dbc.Row([
              dbc.Col([
                  dbc.Row([
                      dbc.Col(controls)
                  ],  align=&quot;start&quot;), 
                  dbc.Row([
                      dbc.Col([
                          html.Br(),
                          dbc.Row([
                              dbc.Col([html.Div(id = 'txt1')
                              ])
                          ]),
                          html.Br(),
                          dbc.Row([
                              dbc.Col([html.Div(id = 'txt2')])
                          ])
                      ])
                  ])
              ],xs = 2)
              ,
              dbc.Col([
                  dbc.Row([
                      dbc.Col([html.Div(id = 'plot_title')],)
                  ]),
                  dbc.Row([
                      dbc.Col(dcc.Graph(id=&quot;crop-graph&quot;)),
                      #dbc.Col(dcc.Graph(id=&quot;cluster-graph&quot;))
                  ])
              ])
          ],), 
      ],
      fluid=True,
  )
      
  
  
  
  # Callbacks #####################################################################
  
  # Weighting selection.
  @app.callback( # Dataframe PROD or AREA
      Output('columns_dd', 'options'),
      # layout element: dcc.RadioItems(id='weight_dd'...)
      [Input('weight_dd', 'value')])
  def set_columns_options(weight):
      varz =  [{'label': i, 'value': i} for i in all_options[weight]]
      return [{'label': i, 'value': i} for i in all_options[weight]]
  
  # Columns selection
  @app.callback( 
      Output('columns_dd', 'value'),
      [Input('columns_dd', 'options')])
  def set_columns(available_options):
      return available_options[1]['value']
  
  # Crop selection
  @app.callback( 
      Output('crop_dd', 'value'),
      [Input('crop_dd', 'options')])
  def set_crops(available_crops):
      return available_crops[0]['value']
  
  
  
  
  # Make a figure based on the selections
  @app.callback( # Columns 2m_temp_prod, or....
      Output('crop-graph', 'figure'),
      [Input('weight_dd', 'value'),
       Input('crop_dd', 'value'),
       Input('columns_dd', 'value')])
  def make_graph(weight, available_crops, vals):
      
      # data source / weighting
      if weight == 'Production':
          dfv = df_vals_prod
          #dfd = df_deltas_prod
      if weight == 'Area':
          dfv = df_vals_area
          #dfd= df_deltas_area
      
      # plotly figure
      fig = make_subplots(specs=[[{&quot;secondary_y&quot;: True}]])
      if 'precip' in vals:
          fig.add_trace(go.Scatter(x=df_vals_prod[available_crops]['time'], y=round((dfv[available_crops][vals].cumsum()/25.4),2),
                                  mode = 'lines', line=dict(color='lime', width=4),
                                  hovertemplate='Date: %{x|%d %b %H%M} UTC&lt;br&gt;Precip: %{y:.2f} in&lt;extra&gt;&lt;/extra&gt;'), secondary_y=False)
      else:
          fig.add_trace(go.Scatter(x=df_vals_prod[available_crops]['time'], y=round(((dfv[available_crops][vals]-273.15)*(9/5))+32,2),
                                  mode = 'lines', line=dict(color='red', width=4),
                                  hovertemplate='Date: %{x|%d %b %H%M} UTC&lt;br&gt;Temp: %{y:.2f} F&lt;extra&gt;&lt;/extra&gt;'), secondary_y=False)
      #fig.add_trace(go.Bar(x=dfd[available_crops].index, y=dfd[available_crops][deltas]), secondary_y=True)
      fig.update_layout(title=dict(text='Crop: ' + available_crops.title() + ', Weight: ' +weight+ ', Variable: '+ vals))
      fig.update_layout(yaxis2_showgrid=False,showlegend=False, 
                        width=1500,height=800,yaxis_zeroline=False, yaxis2_zeroline=False)
      fig.update_layout(template=&quot;plotly_dark&quot;, plot_bgcolor='#272B30', paper_bgcolor='#272B30')
      fig.update_yaxes(automargin=True)
      return(fig)
  
  app.run_server(mode='external', port = 8099)
  </code></pre>
  <p>Notice how the dict names and the dataframe columns within the dicts have similar names. I would like those to stay together on the plot.</p>
  <p>For example, the user selects Weighting: Production, Crop: Corn, Forecast Variable: 2m_temp_prod. This should plot a line plot. Now, I want to add a secondary y-axis, where 2m_temp_24hdelta_prod is plotted (comes from df_deltas_prod['corn']['2m_temp_24hdelta_prod']. Notice though that I don't want a dropdown for this, I just want it to be plotted based on the other dropdown selections. Finally, if the user switches to Weighting: Area, Crop: Corn, Forecast Variable: 2m_temp_area, the secondary y-axis would have plotted df_deltas_area['corn']['2m_temp_24hdelta_area']. Hope this is clear.</p>