Adding simple dropdown to Bokeh plot using pandas data

I am very new to Bokeh and cannot seem to find any really good examples of a simple dropdown plot with data from a pandas dataframe. I am working with a dictionary that has 4 different keys, where each key contains a dataframe.

df_vals.keys()
dict_keys(['corn', 'soybeans', 'winterwheat', 'springwheat'])

df_vals['corn'].head()
time    2m_temp_prod    2m_temp_area    total_precip_prod   total_precip_area
0   2020-09-16 00:00:00 299.346777  299.799234  0.000000    0.000000
1   2020-09-16 06:00:00 294.039512  294.443352  0.191070    0.286952
2   2020-09-16 12:00:00 292.959274  293.182931  0.155765    0.216606
3   2020-09-16 18:00:00 301.318046  301.767516  0.421768    0.485691
4   2020-09-17 00:00:00 300.623567  300.979650  0.363572    0.501164

Next, I can add this data to a source.

source=ColumnDataSource(data=df_vals['corn'])

Plotting from here is simple.

p1=figure(x_axis_type='datetime')
p1.line(x='time', y='2m_temp_prod',source=source)
show(p1)

This does exactly what I want. It plots a line plot with datetime as the x-axis. However, now I want to add a dropdown widget to switch between 2 columns in df_vals['corn'] (2m_temp_prod and total_precip_prod). I have tried this code below but it is not working and I am not sure if that’s even the right way to go about it.

def update_plot(attr, old, new):
    if new == 'total_precip_prod': 
        source.data = {
            'x' : df_vals['corn']['time'],
            'y' : df_vals['corn']['total_precip_prod'].cumsum()
        }
select = Select(title="hi", options=['2m_temp_area', 'total_precip_prod'], value='2m_temp_area')
select.on_change('value', update_plot)
 
# Create layout and add to current document
layout = row(select, p1)
curdoc().add_root(layout)

Ideally, the button would have two options: temps and precip. How would I go about do this?

When you create a column data source from a Pandas data frame, the data dict has the keys set to column names and the values set to the columns themselves. You use that fact in the call to p1.line() where you set x and y to the right columns in the data frame.

When you later call the callback by changing the value of the Select widget, you remove everything from the column data source, including those columns that are used by p1.line and instead add columns x and y. At that point, p1.line doesn’t know that it should use those names.

You should always keep the names of the columns in any column data source, don’t change them unless you’re absolutely certain you must do that. In your particular case, it seems like x is always constant while y changes. So just create a column data source with two columns, x and y, populate those columns manually, and update the y column based on the value of the select widget.

This makes sense but I still have no idea how to accomplish the task. I can’t seem to find any simple examples online where there is a dropdown option to change the data within a single dataframe. I would appreciate some further guidance here, or a simple example.

Create your data source as

ColumnDataSource(data=dict(x=df_vals['corn']['time'],
                           y=df_vals['corn']['2m_temp_area']))

and replace the body of your callback with

source.data['y'] = df_vals['corn'][new].cumsum()

I did not test it but I think it should work.