# Hands-On Tutorial: Bokeh Webapp[¶](https://knowledge.dataiku.com/latest/courses/advanced-code/visualization/bokeh-hands-on.html#hands-on-tutorial-bokeh-webapp "Permalink to this headline")

In this tutorial, we’ll create a simple Bokeh webapp in Dataiku. It’s a scatter plot on sales data from the fictional Haiku T-shirt company, similar to the data used in the Basics tutorials.

## Let’s Get Started![¶](https://knowledge.dataiku.com/latest/courses/advanced-code/visualization/bokeh-hands-on.html#lets-get-started "Permalink to this headline")

### Prerequisites[¶](https://knowledge.dataiku.com/latest/courses/advanced-code/visualization/bokeh-hands-on.html#prerequisites "Permalink to this headline")

* Some familiarity with Python.

### Technical Requirements[¶](https://knowledge.dataiku.com/latest/courses/advanced-code/visualization/bokeh-hands-on.html#technical-requirements "Permalink to this headline")

* An instance of Dataiku DSS - version 8.0 or above (Dataiku Online can also be used);

### Webapp Overview[¶](https://knowledge.dataiku.com/latest/courses/advanced-code/visualization/bokeh-hands-on.html#webapp-overview "Permalink to this headline")

We will create a webapp which displays an interactive scatter plot showing the total number of item orders by customer age. To make it interactive, we will add a dropdown menu to filter on item category, as well as sliders to filter on age.

The finished webapp is shown below.

## Create Your Project[¶](https://knowledge.dataiku.com/latest/courses/advanced-code/visualization/bokeh-hands-on.html#create-your-project "Permalink to this headline")

Create your project by selecting one of these options:

### Import a Starter Project[¶](https://knowledge.dataiku.com/latest/courses/advanced-code/visualization/bokeh-hands-on.html#import-a-starter-project "Permalink to this headline")

From the Dataiku homepage, click **+New Project > DSS Tutorials > Developer > Visualization (Tutorial)**.

Note

You can also download the starter project from this website and import it as a zip file.

### Continue From the Previous Hands-On Tutorial[¶](https://knowledge.dataiku.com/latest/courses/advanced-code/visualization/bokeh-hands-on.html#continue-from-the-previous-hands-on-tutorial "Permalink to this headline")

If you are following the Academy Visualization course and have already completed the previous hands-on lesson, you can begin this lesson by continuing with the same project you created earlier.

### Download and Import Dataset Into New Project[¶](https://knowledge.dataiku.com/latest/courses/advanced-code/visualization/bokeh-hands-on.html#download-and-import-dataset-into-new-project "Permalink to this headline")

Alternatively, you can download the Orders\_enriched\_prepared dataset and import it into a new project.

## Create a New Bokeh Webapp[¶](https://knowledge.dataiku.com/latest/courses/advanced-code/visualization/bokeh-hands-on.html#create-a-new-bokeh-webapp "Permalink to this headline")

To create a new empty Bokeh webapp:

* In the top navigation bar, select **Webapps** from the Code (</>) menu.

* Click **+ New Webapp > Code Webapp > Bokeh > An empty Bokeh app**.

* Type a simple name for your webapp, such as `bokeh webapp`, and click **Create**.

You will land on the **View** tab of the webapp, which is empty for the moment, as we haven’t started creating the webapp yet.

* Navigate to the **Settings** tab of the webapp.

## Explore the Webapp Editor[¶](https://knowledge.dataiku.com/latest/courses/advanced-code/visualization/bokeh-hands-on.html#explore-the-webapp-editor "Permalink to this headline")

The webapp editor is divided into two panes:

* The left pane allows you to see and edit the Python code underlying the webapp.

* The right pane gives you several views on the webapp.

* The **Preview** tab allows you to write and test your code in the left pane, while receiving visual feedback in the right pane. At any time you can save or reload your current code by clicking on the **Save** button or the **Preview** button.

* The **Python** tab allows you to look at different portions of the code side-by-side in the left and right panes.

* The **Log** is useful for troubleshooting problems.

* The **Settings** tab allows you to set the code environment for this webapp, if you want it to be different from the project default.

Note

In the **Settings** tab, under **Code env**, you can see the code environment that the webapp is using. It’s currently set to inherit the project default environment, which in this case is the DSS builtin environment.

As the builtin environment already contains the necessary packages for this tutorial, you do not need to change this. However, if you wish to use another code environment for this webapp or for another one, you can change it from the **Code env** dropdown menu, and then click **Save**.

Learn more about code environments in Dataiku in this article.

## Code the Webapp[¶](https://knowledge.dataiku.com/latest/courses/advanced-code/visualization/bokeh-hands-on.html#code-the-webapp "Permalink to this headline")

Let’s add the code behind the Python Bokeh webapp.

### Import Packages and Set up Data[¶](https://knowledge.dataiku.com/latest/courses/advanced-code/visualization/bokeh-hands-on.html#import-packages-and-set-up-data "Permalink to this headline")

* In the **Python** tab, replace the sample import statement with the following ones, so that we’ll have the necessary libraries to create the webapp and parameterize its inputs.

§ from bokeh.io import curdoc

§ from bokeh.layouts import row, widgetbox

§ from bokeh.models import ColumnDataSource

§ from bokeh.models.widgets import Slider, TextInput, Select

§ from bokeh.plotting import figure

§ import dataiku

§ import pandas as pd

§ # Parameterize webapp inputs

§ input\_dataset = "Orders\_enriched\_prepared"

§ x\_column = "age"

§ y\_column = "total"

§ time\_column = "order\_date\_year"

§ cat\_column = "tshirt\_category"

By specifying this information up front, it will be easier for us to generalize the webapp later.

### The Dataiku API[¶](https://knowledge.dataiku.com/latest/courses/advanced-code/visualization/bokeh-hands-on.html#the-dataiku-api "Permalink to this headline")

* Next, add the following code to the Python tab to access a Dataiku dataset as a pandas dataframe. Then, we’ll add code which extracts the customer age and total amount spent from the pandas dataframe to define the source data for the visualization as a `ColumnDataSource`.

§ # Set up data

§ mydataset = dataiku.Dataset(input\_dataset)

§ df = mydataset.get\_dataframe()

§ x = df[x\_column]

§ y = df[y\_column]

§ source = ColumnDataSource(data=dict(x=x, y=y))

* Click **Save** in the upper right corner of the page.

Nothing is displayed yet because we haven’t created the visualization, but there are no errors in the log.

### Define the Visualization[¶](https://knowledge.dataiku.com/latest/courses/advanced-code/visualization/bokeh-hands-on.html#define-the-visualization "Permalink to this headline")

* Add the following code to the Python tab to define the output visualization, and then click **Save**:

§ # Set up plot

§ plot = figure(plot\_height=400, plot\_width=400, title=y\_column+" by "+x\_column,

§ tools="crosshair,pan,reset,save,wheel\_zoom",

§ x\_range=[min(x), max(x)], y\_range=[min(y),max(y)])

§ plot.scatter('x', 'y', source=source)

§ # Set up layouts and add to document

§ inputs = widgetbox()

§ curdoc().add\_root(row(inputs, plot, width=800))

This code:

* creates a `plot` object with the desired height and width properties;

* defines the title of the plot using the X- and Y-Axis column names;

* configures a set of built-in Bokeh plot tools;

* computes the minimum and maximum values of customer age and total, and uses those to define the axis limits;

* and defines the visualization as a scatter plot that plots data from the `source` defined above.

The last two lines define the layout of the webapp and adds it to the current “document”. For now, we’ll include an empty widgetbox that we’ll populate in a moment when we add the interactivity.

The preview should now show the current (non-interactive) scatter plot.

## Add Interactivity[¶](https://knowledge.dataiku.com/latest/courses/advanced-code/visualization/bokeh-hands-on.html#add-interactivity "Permalink to this headline")

The current scatter plot includes all orders from 2013-2017, across all types of t-shirts sold. Now, let’s add the ability to select a subset of years, and a specific category of t-shirt. To do this, we need to make changes to the Python code.

### Define Widgets[¶](https://knowledge.dataiku.com/latest/courses/advanced-code/visualization/bokeh-hands-on.html#define-widgets "Permalink to this headline")

Warning

The code in this section should be added **after** the code which sets up the plot, but **before** the code which defines the layout of the webapp. See the image below for reference.

* In the Python tab, **after** the `# Set up plot` block of code, and **before** the `# Set up layouts and add to document` block, add the following:

§ # Set up widgets

§ text = TextInput(title="Title", value=y\_column+" by "+x\_column)

§ time = df[time\_column]

§ min\_year = Slider(title="Time start", value=min(time), start=min(time), end=max(time), step=1)

§ max\_year = Slider(title="Time max", value=max(time), start=min(time), end=max(time), step=1)

§ cat\_categories = df[cat\_column].unique().tolist()

§ cat\_categories.insert(0,'All')

§ category = Select(title="Category", value="All", options=cat\_categories)

This code defines four widgets:

* `text` accepts text input to be used as the title of the visualization.

* `min\_year` and `max\_year` are sliders that take values from 2013 to 2017 in integer steps. Their default values are 2013 and 2017, respectively.

* `category` is a selection that has an option for each t-shirt category, plus “All”. Its default value is “All”.

### Set Up Update Functions and Callbacks[¶](https://knowledge.dataiku.com/latest/courses/advanced-code/visualization/bokeh-hands-on.html#set-up-update-functions-and-callbacks "Permalink to this headline")

Next, we’ll add the instructions on how to update the webapp when a user interacts with it.

* Directly after the `# Set up widgets` code block, add the following code to the Python tab:

§ #Set up update functions and callbacks

§ def update\_title(attrname, old, new):

§ plot.title.text = text.value

§ def update\_data(attrname, old, new):

§ category\_value = category.value

§ selected = df[(time>=min\_year.value) & (time<=max\_year.value)]

§ if (category\_value != "All"):

§ selected = selected[selected[cat\_column].str.contains(category\_value)==True]

§ # Generate the new plot

§ x = selected[x\_column]

§ y = selected[y\_column]

§ source.data = dict(x=x, y=y)

* When the title text is changed, `update\_title()` updates `plot.title.text` to the new value.

* When the sliders or the select widget are changed, `update\_data` takes the input dataframe `df` and uses the widget selections to filter the dataframe to only use records with the correct order year and t-shirt category. It then defines the X and Y axes of the scatter plot to be the age and order total from the filtered dataframe.

Next, we’ll add the two following pieces of code that listen for changes to the widget values using the `on\_change()` method, which calls the functions above to update the webapp:

* Add the following code as a new line after the `update\_title()` function and before the `update\_data()` function:

§ text.on\_change('value', update\_title)

* Next, add the following code **after** the `update\_data()` function:

§ for w in [min\_year, max\_year, category]:

§ w.on\_change('value', update\_data)

### Update Inputs[¶](https://knowledge.dataiku.com/latest/courses/advanced-code/visualization/bokeh-hands-on.html#update-inputs "Permalink to this headline")

Finally, change the definition of `inputs` as follows, to include the four widgets so that they are displayed in the webapp.

* Right under the `# Set up layouts and add to document` comment, replace the `inputs = widgetbox()` line of code with the following. See the image below for reference.

* Then click **Save** and **Preview**.

* Click to start the backend if prompted.

§ inputs = widgetbox(text, min\_year, max\_year, category)

After you’ve saved your work and refreshed the preview, the Preview tab should now show the interactive scatter plot we just created.

## Publish the Webapp on a Dashboard[¶](https://knowledge.dataiku.com/latest/courses/advanced-code/visualization/bokeh-hands-on.html#publish-the-webapp-on-a-dashboard "Permalink to this headline")

When you are done with editing, you can easily publish your webapp on a dashboard.

* Click **Actions** in the top-right corner of the screen.

* From the **Actions** menu, click **Publish**.

* Select the dashboard and slide you wish to publish your webapp on. (The default is fine).

* Click **Create**.

You are navigated to the **Edit** tab of the dashboard.

* There you can drag and resize your webapp, or change its title and display options from the Tile sidebar menu.

* Click **Save** when you’re done.

* Click **View** to see how your webapp is displayed on the dashboard.

Note

You can learn more about dashboard concepts in the product documentation.

## What’s Next?[¶](https://knowledge.dataiku.com/latest/courses/advanced-code/visualization/bokeh-hands-on.html#what-s-next "Permalink to this headline")

Using Dataiku, you have created an interactive Bokeh webapp and published it to a dashboard.

To go further, you can:

* examine this sample webapp further on the Dataiku gallery;

* see the Bokeh gallery (external) for further inspiration on what is possible in Bokeh webapps;

* see the product documentation for further details on using Bokeh in Dataiku.
