> For the complete documentation index, see [llms.txt](https://fennaf.gitbook.io/bfvm22prog1/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://fennaf.gitbook.io/bfvm22prog1/data-visualisation/bokeh-applications.md).

# Bokeh applications

Previously we looked into the building blocks of an application such as plots and widgets. **CREATING PLOTS AND WIDGETS** is a concept you should be familiar with.

The first step in an application is to build plots, tools and widgets. The next step is to **DEFINE CALLBACK FUNCTION**. The callback function is a function that tells the application how to respond when a user interacts with your application. The callback function is the interface between the widgets and the plot. It tells how to change the plot.

The final step is **CREATE LAYOUTS** in order to present the plots. This is a concept you should be familiar with as well.

Combining the three steps will render in a Bokeh application.

See: <https://docs.bokeh.org/en/latest/docs/user_guide/interaction/callbacks.html#customjs-for-widgets>

```python
#basic app outline
from bokeh.io import curdoc
# Create plots and widgets
# Add callbacks
# Arrange plots and widgets in layouts
curdoc().add_root(layout)
```

Whenever we create an application, bokeh creates a blank document or a canvas for that application. This application is known as `curdoc` abbreviation for current document. We can add plot, widgets and other elements to this blank document with the `add_root` method.

## Study Case: interactive plotting distribution of data

Let us look at an example. A plot with a select menu that changes interactively the distribution of the data and the plot showing the data

## Create plots and widget

```python
#import
from bokeh.models import Select, ColumnDataSource
from bokeh.plotting import figure
from numpy.random import random, normal, lognormal

#create data
source = ColumnDataSource(data = {'x':random(500), 'y':random(500)})

#create plot
p =figure()
p.circle(x='x', y='y', source=source)

#create widget
menu = Select(options=['uniform', 'normal', 'lognormal'], value='uniform',
       title = 'select distribution of your choice')
```

## Callback: the interactivity layer

The fundamental purpose of a bokeh application is to make use of interactivity. We can combine plot and widget with a callback function. In the following example, the callback function is set to `random` if the user selects a *uniform* distribution, the function is set to `normal` if the user selects a *normal* distribution, the function is set to `lognormal` if the user selects a *lognormal* distribution.

```python
def callback(attr, old, new):
    if menu.value == 'uniform': f = random
    elif menu.value == 'normal': f = normal
    else: f = lognormal
    source.data={'x': f(size=500), 'y': f(size=500)}
```

Next we need to call the callback function if the widget is triggered. In the example below we use the `.on_change()` method of the widget. When the widget is triggered it calls the callback function passing the value

```python
menu.on_change('value', callback)
```

## Arrange plots and widgets in layouts

Finally we create the layout.

```python
# Arrange plots and widgets in layouts
from bokeh.io import curdoc
from bokeh.layouts import column 
layout = column(menu, p)
curdoc().add_root(layout)
```

## Launch application

In order to run the application, we need to put all the code in python script. The preceding code was saved into a file called `demo_bokeh.py`. In order to run the application, we can open the terminal and type the command

```
bokeh serve --show demo_bokeh.py
```

This shows initially the following

![](/files/-MLrAKWGBOIpen4S3dyC)
