Unlocking Insights with Interactive Dashboards: A Bokeh + Pandas Tutorial
Interactive dashboards have become vital tools for data-driven organizations, enabling decision makers to visually explore data, uncover insights, and track key metrics. By allowing users to intuitively navigate and drill down into their data, modern dashboards fulfill the promise of self-service analytics.
Consider these statistics on the growing adoption of dashboards:
- 45% of companies believe AI and analytics will completely transform their organization‘s operations (IBM)
- Managers using visual data discovery tools are 28% more likely to find timely information than those who rely solely on managed reporting (TDWI)
- Organizations that use visual data discovery are 69% more likely to get the right information to the right person at the right time (Aberdeen Group)
Python has emerged as the leading platform for data science, and libraries like Bokeh bring powerful interactive visualization capabilities to the ecosystem. Let‘s explore how to harness Bokeh and Pandas to build dashboards that empower your team to make smarter, faster decisions.
Why Bokeh for Dashboards?
Bokeh is a flexible and powerful Python library for building interactive web-based visualizations. It has several key features that make it an excellent fit for dashboarding:
- Declarative, concise syntax for specifying plots
- Seamless integration with Pandas DataFrames
- Wide variety of chart types and styling options
- Interactive tools like pan, zoom, and hover
- Ability to link plots and add user-driven filters
- High-performance even with large, streaming datasets
- Works in Jupyter notebooks and standalone web apps
While other Python viz libraries like Plotly and Dash are also great choices, Bokeh‘s simplicity and tight integration with the PyData stack make it a go-to for many data scientists. It provides a nice balance between ease-of-use and advanced customization.
Planning Your Dashboard
Before diving into the code, it‘s important to consider the purpose and audience for your dashboard. Some key questions to ask:
- Who will be using this dashboard and what are their goals?
- What questions should the dashboard help answer?
- What are the key metrics or KPIs to surface?
- How will the dashboard be used in a workflow?
- What interactivity would provide the most value?
For our example, let‘s consider a dashboard to help a manufacturing company monitor sensor data from their equipment. The main goals will be to track sensor values over time, analyze the relationships between sensors, and allow engineers to investigate anomalies.
Preparing the Data
Often the most time-consuming part of building a dashboard is wrangling the data into a suitable format. Pandas is the Swiss Army knife of data manipulation in Python. We‘ll generate a fake dataset of sensor readings to demonstrate:
import numpy as np
import pandas as pd
dates = pd.date_range(‘2023-01-01‘, periods=1000, freq=‘D‘)
sensor_1 = np.random.randint(50,100,size=(1000))
sensor_2 = np.random.randint(10,20,size=(1000))
sensor_3 = np.random.randint(0,10,size=(1000))
sensor_4 = np.random.randint(30,40,size=(1000))
df = pd.DataFrame({‘Date‘: dates, ‘Sensor_1‘: sensor_1,
‘Sensor_2‘: sensor_2, ‘Sensor_3‘: sensor_3,
‘Sensor_4‘: sensor_4})
df.head()
This gives us a DataFrame with 1000 rows of sample sensor measurements:
| Date | Sensor_1 | Sensor_2 | Sensor_3 | Sensor_4 |
|---|---|---|---|---|
| 2023-01-01 | 92 | 10 | 3 | 35 |
| 2023-01-02 | 54 | 14 | 9 | 39 |
| 2023-01-03 | 91 | 18 | 6 | 35 |
| 2023-01-04 | 55 | 11 | 8 | 33 |
| 2023-01-05 | 74 | 13 | 0 | 35 |
In a real scenario you‘d likely query this data from a database or read from CSVs. Pandas makes it easy to merge data from multiple sources and get it into a tidy format for visualization.
Building the Visualization
Now comes the fun part – creating our Bokeh plots! We‘ll make several different chart types to include in the dashboard.
Line Plot
First a line plot to show the sensor readings over time:
from bokeh.plotting import figure
from bokeh.io import output_notebook, show
from bokeh.models import ColumnDataSource, DatetimeTickFormatter
output_notebook()
source = ColumnDataSource(df)
p = figure(width=800, height=250, x_axis_type="datetime")
p.line(x=‘Date‘, y=‘Sensor_1‘, line_width=2, source=source, legend_label=‘Sensor 1‘)
p.line(x=‘Date‘, y=‘Sensor_2‘, line_width=2, source=source, color=‘orange‘, legend_label=‘Sensor 2‘)
p.line(x=‘Date‘, y=‘Sensor_3‘, line_width=2, source=source, color=‘green‘, legend_label=‘Sensor 3‘)
p.line(x=‘Date‘, y=‘Sensor_4‘, line_width=2, source=source, color=‘red‘, legend_label=‘Sensor 4‘)
p.xaxis.formatter=DatetimeTickFormatter(months="%b %Y")
p.legend.location = "top_left"
show(p)

We start by creating a ColumnDataSource from our Pandas DataFrame, which lets us efficiently pass the data to the plot. Then we initialize a figure specifying datetime for the x-axis.
Next we add a line glyph for each sensor column, specifying visual properties like line color and width. The legend is automatically populated and interactivity like zooming and panning works out of the box!
Area Chart
Next let‘s make a stacked area chart to show the percentage each sensor contributes to the total over time:
areas = df.drop(‘Date‘, axis=1)
p = figure(x_axis_type="datetime", width=800, height=250)
p.varea_stack(stackers=areas.columns, x=‘Date‘, color=Spectral4, legend_label=areas.columns, source=source)
p.legend.location = "top_left"
p.legend.click_policy = "hide"
show(p)

Here we use the varea_stack function which makes it trivial to create a stacked area chart from multiple columns. We can hide the legend entries on click to filter the plot.
Bar Chart
How about a bar chart to show the average values by month:
df_monthly = df.resample(‘M‘, on=‘Date‘).mean().reset_index()
source = ColumnDataSource(df_monthly)
p = figure(x_axis_type="datetime", width=800, height=250)
p.vbar(x=‘Date‘, top=‘Sensor_1‘, width=timedelta(days=25), source=source, color=‘blue‘, legend_label=‘Sensor 1‘)
p.vbar(x=‘Date‘, top=‘Sensor_2‘, width=timedelta(days=25), source=source, color=‘red‘, legend_label=‘Sensor 2‘)
p.xaxis.formatter=DatetimeTickFormatter(months="%b %Y")
p.legend.location = "top_left"
p.add_tools(HoverTool(tooltips=[("Sensor 1", "@Sensor_1{0.0}"), ("Sensor 2", "@Sensor_2{0.0}")], formatters={‘@Sensor_1‘:‘numeral‘, ‘@Sensor_2‘:‘numeral‘}))
show(p)

To aggregate the daily data by month, we use Pandas‘ handy resample function. Then we add vbar glyphs for each sensor, specifying a width in days to center the bars on the month.
The HoverTool lets us display nicely formatted tooltips when mousing over the bars. We can directly reference columns from the data source.
Scatter Plot
Finally we‘ll create a scatter plot to visualize the relationship between two sensors:
p = figure(width=400, height=400)
p.scatter(x=‘Sensor_3‘, y=‘Sensor_4‘, size=5, color=‘green‘, alpha=0.5, source=source)
p.xaxis.axis_label = ‘Sensor 3‘
p.yaxis.axis_label = ‘Sensor 4‘
show(p)

Scatter plots are a great way to look for correlations between variables. We can add a regression line to quantify the relationship.
Layout and Linking
We‘ve got all our individual plots, now to put them together into a cohesive dashboard! Bokeh provides several options for layouts, but gridplot is an easy way to arrange plots in a grid:
from bokeh.layouts import gridplot
dashboard = gridplot([p1, p2], [p3, p4], sizing_mode=‘scale_width‘)
show(dashboard)

The sizing_mode makes the layout responsive so it resizes nicely.
To make the plots interactive with each other, we can add tools like RangeTool:
from bokeh.models import RangeTool
p1.x_range = p2.x_range
select = figure(height=50, width=800, y_range=p1.y_range, tools="", toolbar_location=None)
range_tool = RangeTool(x_range=p1.x_range)
range_tool.overlay.fill_color = "green"
range_tool.overlay.fill_alpha = 0.2
select.ygrid.grid_line_color = None
select.add_tools(range_tool)
select.toolbar.active_multi = range_tool
layout = column(p1, select, p2)
show(layout)
Now the user can drag to select a region on the lower plot and the zoom is reflected in the top plot as well. These kind of linked interactions help guide the user to insights.
Deploying Your Dashboard
Once you‘ve crafted the perfect dashboard in a Jupyter notebook, it‘s time to share it with the world! Bokeh makes it easy to deploy your visualization as a standalone web app.
First, create a Python script dashboard.py with your plot code wrapped in a function:
# dashboard.py
from bokeh.io import curdoc
from bokeh.layouts import column
def make_dashboard():
# Your plot code here
plot1 = make_plot1()
plot2 = make_plot2()
...
return column(plot1, plot2)
doc = curdoc()
doc.add_root(make_dashboard())
Then you can run bokeh serve dashboard.py from the command line and navigate to http://localhost:5006/dashboard in your web browser to view the app.
Bokeh server apps can dynamically update with new data, giving you true real-time dashboards. You can also add Python callbacks to respond to user interactions.
When you‘re ready to share your dashboard with a wider audience, platforms like Heroku or Anaconda Enterprise make it straightforward to deploy public-facing Bokeh apps.
Conclusion
We‘ve seen how the combination of Pandas for data wrangling and Bokeh for visualization gives data scientists a powerful toolkit for building interactive dashboards. The declarative API and built-in interactivity keeps your code concise while producing highly functional plots.
The key to an effective dashboard is starting with the right questions and working backwards to charts that provide relevant insights. Interactivity like cross-filtering, drill-downs, and tooltips guide the user to explore their data.
Bokeh integrates seamlessly with the PyData ecosystem, so you can create dashboards that leverage the full power of libraries like NumPy, SciPy, Dask, and scikit-learn. You can even dynamically update your visualizations with real-time data or embed machine learning models.
As a flexible, open-source library, Bokeh is also a foundation you can build on with custom extensions and visualizations. It has an active community continually enhancing its capabilities.
The landscape of Python web frameworks for data science is rapidly evolving, with entrants like Dash, Streamlit, Voilà, and Panel providing new options for building analytical web apps. But the core concepts of tidy data, declarative plotting, and thoughtful interactivity that Bokeh embodies are essential for any data scientist working on dashboards and visualizations.
Empowering your team with well-crafted dashboards is a key component of building a data-driven culture. Python and Bokeh give you the tools to unlock insights and communicate them with impact. Now go forth and viz!