1

I have a pandas dataframe with multiple columns. I have multiple scatter plots where the x-axis is a different column from the dataframe while the y-axis is the same across all the figures. I want to be able to change the y-axis based on the selected value in a dropwdown button. I'm new using bokeh, I haven't be able to figure how exactly to build the callback function for this case. Any help is much appreciated!

    def callback(attr, old, new):
        y_axis = select.value
        source.data = {'y' : y_axis}
        p1.circle.y = y_axis



    columns = {'TC2B':'Temperature 2B','TC1B':'Temperature 1B', 'PCV-2006 Pos':'2006 valve position', 
       'TCV-2008 DownS Ctrl PV':'Down Stream'}

    select = Select(title='Y axis:', value='TCV-2008 Pos', options=list(columns.keys()))

    y_select = select.value
    color_select = 'TC2B'#'PCV-2006 Pos'
    #source = ColumnDataSource(data={'y':y_select})
    source = ColumnDataSource(data)



   p1 = figure(x_axis_label='Temperature 1B', y_axis_label=columns[y_select])

   p1.circle(x='TC1B', 
        y=y_select,
        source=source)

   p2 = figure(x_axis_label='2006 valve position', y_axis_label=columns[y_select])
   p2.circle(x='PCV-2006 Pos', 
        y=y_select,
        source=source)

   p3 = figure(x_axis_label='Down Stream', y_axis_label=columns[y_select])
   p3.circle(x='TCV-2008 DownS Ctrl PV', 
        y=y_select,
        source=source)

   p1.y_range = p2.y_range = p3.y_range

   select.on_change('value', callback)

   layout = column(select, row(column(p1, p2, p3)))

   curdoc().add_root(layout)
  • Next time you should post a complete and functional example, imports included. More people will be willingn to help you – ChesuCR Aug 14 '19 at 14:49

1 Answers1

0

You can recreate the plots again from scratch in the onchange callback and update the layout content. Take a look at this:

from bokeh.models import ColumnDataSource, Select
from bokeh.plotting import figure
from bokeh.layouts import column, row
from bokeh.io import curdoc
import numpy as np

N = 3000
data = {
    'X': np.random.random(size=N) * 100,
    'Y': np.random.random(size=N) * 100,
    'Z': np.random.random(size=N) * 100,
    'A': np.random.random(size=N) * 100,
    'B': np.random.random(size=N) * 100,
    'C': np.random.random(size=N) * 100,
}

select = Select(title='Y axis:', value='Y', options=list(data.keys()))

source = ColumnDataSource(data=data)

p1 = figure(
    x_axis_label='X',
    y_axis_label='Y'
)

c1 = p1.circle(
    x='X',
    y='Y',
    source=source
)

p2 = figure(
    x_axis_label='A',
    y_axis_label='Y'
)
c2 = p2.circle(
    x='A',
    y='Y',
    source=source
)

p1.y_range = p2.y_range

r = row(children=[p1, p2])
layout = column(select, r)

def onchange_value(attr, old, new):
    p1 = p2 = None
    p1 = figure(
        x_axis_label='X',
        y_axis_label=new
    )

    p1.circle(
        x='X',
        y=new,
        source=source
    )

    p2 = figure(
        x_axis_label='A',
        y_axis_label=new
    )
    p2.circle(
        x='A',
        y=new,
        source=source
    )
    r.children = [p1, p2]

select.on_change('value', onchange_value)

curdoc().add_root(layout)

Note: You can also read this other question about updating the layout dynamically to get more ideas

ChesuCR
  • 9,352
  • 5
  • 51
  • 114