I have a script to plot the prices of some share that the user wants to look at : he can choose the shares via a Dropdown button and Bokeh will draw the curve accordingly. (I am working in jupyter notebook) :
from bokeh.io import output_notebook, show
from bokeh.plotting import figure
output_notebook()
my code is the following :
from bokeh.models import Callback, ColumnDataSource, Select,CustomJS
from bokeh.plotting import figure, show, gridplot
from bokeh.models.widgets.layouts import VBox
import pandas as pd
shares = ['AAPL', 'MSFT', 'IBM', 'All']
AAPL = pd.read_csv("http://ichart.yahoo.com/table.csv?s=AAPL&a=0&b=1&c=2000&d=0&e=1&f=2015",parse_dates=['Date'])
MSFT = pd.read_csv("http://ichart.yahoo.com/table.csv?s=MSFT&a=0&b=1&c=2000&d=0&e=1&f=2015",parse_dates=['Date'])
IBM = pd.read_csv("http://ichart.yahoo.com/table.csv?s=IBM&a=0&b=1&c=2000&d=0&e=1&f=2015",parse_dates=['Date'])
max_price = max(AAPL['Adj Close'].max(), MSFT['Adj Close'].max(), IBM['Adj Close'].max()) + 10
min_date = min(AAPL['Date'].min(), MSFT['Date'].min(), IBM['Date'].min())
max_date = max(AAPL['Date'].max(), MSFT['Date'].max(), IBM['Date'].max())
myplot = figure(title="Share price", x_axis_type="datetime", x_range=[min_date,max_date],y_range=[0,max_price],
background_fill='#FFF5EE', plot_width=900, plot_height = 400, outline_line_color= None)
source_AAPL = ColumnDataSource(data=dict(x=AAPL['Date'], y = AAPL['Adj Close'], ytemp = AAPL['Adj Close']))
source_MSFT = ColumnDataSource(data=dict(x=MSFT['Date'], y = MSFT['Adj Close'], ytemp = MSFT['Adj Close']))
source_IBM = ColumnDataSource(data=dict(x=IBM['Date'], y = IBM['Adj Close'], ytemp = IBM['Adj Close']))
myplot.line(x ='x', y ='y', color='#A6CEE3', source = source_AAPL, name='AAPL')
myplot.line(x ='x', y ='y', color='#33A02C', source = source_MSFT, name='IBM')
myplot.line(x ='x', y ='y', color='#FB9A99', source = source_IBM, name='MSFT')
Callback_Shares = CustomJS(args={'source_AAPL': source_AAPL,'source_MSFT': source_MSFT,'source_IBM': source_IBM}, code="""
var f = cb_obj.get('value');
var data_AAPL = source_AAPL.get('data');
var data_MSFT = source_MSFT.get('data');
var data_IBM = source_IBM.get('data');
if (f == 'AAPL') {
data_MSFT['y'] = [0 for i in range(len(data_MSFT['x']))];
data_IBM['y'] = [0 for i in range(len(data_IBM['x']))];
data_AAPL['y'] = data_AAPL['ytemp'] ;
source_AAPL.trigger('change');
source_MSFT.trigger('change');
source_IBM.trigger('change');
}
if (f == 'MSFT') {
data_AAPL['y'] = [0 for i in range(len(data_AAPL['x']))];
data_IBM['y'] = [0 for i in range(len(data_IBM['x']))];
data_MSFT['y'] = data_MSFT['ytemp'] ;
source_AAPL.trigger('change');
source_MSFT.trigger('change');
source_IBM.trigger('change');
}
if (f == 'IBM') {
data_AAPL['y'] = [0 for i in range(len(data_AAPL['x']))];
data_MSFT['y'] = [0 for i in range(len(data_MSFT['x']))];
data_IBM['y'] = data_IBM['ytemp'] ;
source_AAPL.trigger('change');
source_MSFT.trigger('change');
source_IBM.trigger('change');
}
if (f == 'All') {
data_AAPL['y'] = data_AAPL['ytemp'];
data_MSFT['y'] = data_MSFT['ytemp'];
data_IBM['y'] = data_IBM['ytemp'];
source_AAPL.trigger('change');
source_MSFT.trigger('change');
source_IBM.trigger('change');
}"""
)
dropdown = Select(title="Shares:", value=shares[3], options=shares, callback = Callback_Shares)
myfigure = VBox(dropdown, gridplot([[myplot]]))
show(myfigure)
My problem is the figure always shows the 3 curves and does not take into account the choice of the DropDown...
The other answer is unfortunately not an optimal one. As a project maintainer I feel obligated to show the project in the best light. Here is a much simpler complete example that functions the same and works with Bokeh 0.12.4:
from bokeh.models import CustomJS, ColumnDataSource, Select
from bokeh.plotting import figure, output_file, show
from bokeh.layouts import column
import pandas as pd
url = "http://ichart.yahoo.com/table.csv?s=%s&a=0&b=1&c=2000&d=0&e=1&f=2015"
AAPL = pd.read_csv(url % "AAPL", parse_dates=['Date'])
MSFT = pd.read_csv(url % "MSFT", parse_dates=['Date'])
IBM = pd.read_csv(url % "IBM", parse_dates=['Date'])
max_price = max(AAPL['Close'].max(), MSFT['Close'].max(), IBM['Close'].max())
source = ColumnDataSource({
'xAAPL' : AAPL['Date'], 'yAAPL' : AAPL['Close'], 'yAAPLp' : AAPL['Close'],
'xMSFT' : MSFT['Date'], 'yMSFT' : MSFT['Close'], 'yMSFTp' : MSFT['Close'],
'xIBM' : IBM['Date'], 'yIBM' : IBM['Close'], 'yIBMp' : IBM['Close']
})
p = figure(width=500, height=250, x_axis_type="datetime", y_range=[0, max_price+10])
r_aapl = p.line('xAAPL', 'yAAPL', source=source, color='navy', alpha=0.5)
r_msft = p.line('xMSFT', 'yMSFT', source=source, color='red', alpha=0.5)
r_ibm = p.line('xIBM', 'yIBM', source=source, color='green', alpha=0.5)
callback = CustomJS(args=dict(r_aapl=r_aapl, r_msft=r_msft, r_ibm=r_ibm), code="""
f = cb_obj.value;
r_aapl.visible = false;
r_msft.visible = false;
r_ibm.visible = false;
if (f == "AAPL") { r_aapl.visible = true; }
else if (f == "MSFT") { r_msft.visible = true; }
else if (f == "IBM") { r_ibm.visible = true; }
else {
r_aapl.visible = true;
r_msft.visible = true;
r_ibm.visible = true;
}
""")
shares = ['AAPL', 'MSFT', 'IBM', 'All']
multi_select = Select(title="Select Shares:", value=shares[3], options=shares, callback=callback)
output_file("datetime.html")
show(column(multi_select, p))


I should also add, "interactive legends" that allow glyphs to be hidden or muted by clicking on the legend, will be added as as standard feature in 0.12.5.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With