Open In App

How to create charts in bokeh with flask

Last Updated : 30 Dec, 2022
Improve
Improve
Like Article
Like
Save
Share
Report

In this post, we will use the Flask framework to create our web application in Python. The Bokeh library will be used to create interactive bar graphs and we will visualize this graph through a simple frontend HTML page. For this, we will first write the endpoints in Flask which will help us to create Bokeh charts, and then we will create HTML templates that will utilize these Bokeh charts to display them to the user.

pip install flask==2.2.2
pip install bokeh==3.0.1

Steps to Follow:

  1. Create a python file ‘main.py’ that will contain the Flask App.
  2. Create a directory named ‘templates’ and add an HTML file ‘charts.html’.
  3. Run the Flask App and view the output in a browser.
  4. This is the file structure we will follow:
How to Render and Return Plot to View in Flask

 

components() method in Bokeh

It has a components() method which returns HTML components to embed a Bokeh plot. The data for the plot is stored directly in the returned HTML. The returned components assume that BokehJS resources are already loaded. The HTML document or template in which they will be embedded needs to include script tags, either from a local URL or Bokeh’s CDN.

<script src="https://cdn.bokeh.org/bokeh/release/bokeh-3.0.1.min.js"></script>

Syntax: components(models: Model | Sequence[Model] | dict[str, Model], wrap_script: bool = True, wrap_plot_info: bool = True)

Parameters:

  • models (Model|list|dict|tuple): A single Model, a list/tuple of Models, or a dictionary of keys and Models.
  • wrap_script (boolean, optional): If True, the returned javascript is wrapped in a script tag. (default: True)
  • wrap_plot_info (boolean, optional): If True, returns <div> strings. Otherwise, return RenderRoot objects that can be used to build your own divs. (default: True)

Example:

In the below code, we have created sample data for the bar chart. 

Python3




from bokeh.embed import components
from bokeh.plotting import figure
  
# Defining Chart Data
language = [
    'Python', 'Java', 'JavaScript', 'C#', 'PHP', 'C/C++',
    'R', 'Objective-C', 'Swift', 'TypeScript', 'Matlab',
    'Kotlin', 'Go', 'Ruby', 'VBA'
]
popularity = [
    31.56, 16.4, 8.38, 6.5, 5.85, 5.8, 4.08, 2.79, 2.35,
    1.92, 1.65, 1.61, 1.44, 1.22, 1.16
]
  
# Creating Plot Figure
p = figure(
    x_range=language,
    height=400,
    title="Popularity of Programming Languages",
    sizing_mode="stretch_width"
)
  
# Defining Plot to be a Vertical Bar Plot
p.vbar(x=language, top=popularity, width=0.5)
p.xgrid.grid_line_color = None
p.y_range.start = 0
  
# Get Chart Components
script, div = components(p)
  
print(script)
print(div)


Required Bokeh imports to add the graphs in our Flask apps

After defining the Bokeh figure and the chart, we extract the ‘script’ and ‘div’ components from the figure to use in the HTML. The ‘script’ and ‘div’ variable outputs are as follows:

The ‘script’ variable holds the following JS code embedded in an HTML <script> tag.

HTML




<script type="text/javascript">
  (function () {
    const fn = function () {
      Bokeh.safely(function () {
        (function (root) {
          function embed_document(root) {
            const docs_json = '{"a41ce7c7-4f86-4d43-8dbf-c149f5e90c9e":{"version":"3.0.1","title":"Bokeh Application","defs":[],"roots":[{"type":"object","name":"Figure","id":"p1001","attributes":{"height":400,"sizing_mode":"stretch_width","x_range":{"type":"object","name":"FactorRange","id":"p1011","attributes":{"factors":["Python","Java","JavaScript","C#","PHP","C/C++","R","Objective-C","Swift","TypeScript","Matlab","Kotlin","Go","Ruby","VBA"]}},"y_range":{"type":"object","name":"DataRange1d","id":"p1003","attributes":{"start":0}},"x_scale":{"type":"object","name":"CategoricalScale","id":"p1015"},"y_scale":{"type":"object","name":"LinearScale","id":"p1017"},"title":{"type":"object","name":"Title","id":"p1004","attributes":{"text":"Popularity of Programming Languages"}},"renderers":[{"type":"object","name":"GlyphRenderer","id":"p1053","attributes":{"data_source":{"type":"object","name":"ColumnDataSource","id":"p1047","attributes":{"selected":{"type":"object","name":"Selection","id":"p1048","attributes":{"indices":[],"line_indices":[]}},"selection_policy":{"type":"object","name":"UnionRenderers","id":"p1049"},"data":{"type":"map","entries":[["x",["Python","Java","JavaScript","C#","PHP","C/C++","R","Objective-C","Swift","TypeScript","Matlab","Kotlin","Go","Ruby","VBA"]],["top",[31.56,16.4,8.38,6.5,5.85,5.8,4.08,2.79,2.35,1.92,1.65,1.61,1.44,1.22,1.16]]]}}},"view":{"type":"object","name":"CDSView","id":"p1054","attributes":{"filter":{"type":"object","name":"AllIndices","id":"p1055"}}},"glyph":{"type":"object","name":"VBar","id":"p1050","attributes":{"x":{"type":"field","field":"x"},"width":{"type":"value","value":0.5},"top":{"type":"field","field":"top"},"line_color":{"type":"value","value":"#1f77b4"},"fill_color":{"type":"value","value":"#1f77b4"}}},"nonselection_glyph":{"type":"object","name":"VBar","id":"p1051","attributes":{"x":{"type":"field","field":"x"},"width":{"type":"value","value":0.5},"top":{"type":"field","field":"top"},"line_color":{"type":"value","value":"#1f77b4"},"line_alpha":{"type":"value","value":0.1},"fill_color":{"type":"value","value":"#1f77b4"},"fill_alpha":{"type":"value","value":0.1},"hatch_alpha":{"type":"value","value":0.1}}},"muted_glyph":{"type":"object","name":"VBar","id":"p1052","attributes":{"x":{"type":"field","field":"x"},"width":{"type":"value","value":0.5},"top":{"type":"field","field":"top"},"line_color":{"type":"value","value":"#1f77b4"},"line_alpha":{"type":"value","value":0.2},"fill_color":{"type":"value","value":"#1f77b4"},"fill_alpha":{"type":"value","value":0.2},"hatch_alpha":{"type":"value","value":0.2}}}}}],"toolbar":{"type":"object","name":"Toolbar","id":"p1006","attributes":{"tools":[{"type":"object","name":"PanTool","id":"p1032"},{"type":"object","name":"WheelZoomTool","id":"p1033"},{"type":"object","name":"BoxZoomTool","id":"p1034","attributes":{"overlay":{"type":"object","name":"BoxAnnotation","id":"p1035","attributes":{"syncable":false,"level":"overlay","visible":false,"left_units":"canvas","right_units":"canvas","bottom_units":"canvas","top_units":"canvas","line_color":"black","line_alpha":1.0,"line_width":2,"line_dash":[4,4],"fill_color":"lightgrey","fill_alpha":0.5}}}},{"type":"object","name":"SaveTool","id":"p1036"},{"type":"object","name":"ResetTool","id":"p1037"},{"type":"object","name":"HelpTool","id":"p1038"}]}},"left":[{"type":"object","name":"LinearAxis","id":"p1025","attributes":{"ticker":{"type":"object","name":"BasicTicker","id":"p1028","attributes":{"mantissas":[1,2,5]}},"formatter":{"type":"object","name":"BasicTickFormatter","id":"p1026"},"major_label_policy":{"type":"object","name":"AllLabels","id":"p1027"}}}],"below":[{"type":"object","name":"CategoricalAxis","id":"p1019","attributes":{"ticker":{"type":"object","name":"CategoricalTicker","id":"p1022"},"formatter":{"type":"object","name":"CategoricalTickFormatter","id":"p1020"},"major_label_policy":{"type":"object","name":"AllLabels","id":"p1021"}}}],"center":[{"type":"object","name":"Grid","id":"p1024","attributes":{"axis":{"id":"p1019"},"grid_line_color":null}},{"type":"object","name":"Grid","id":"p1031","attributes":{"dimension":1,"axis":{"id":"p1025"}}}]}}]}}';
            const render_items = [{ "docid": "a41ce7c7-4f86-4d43-8dbf-c149f5e90c9e", "roots": { "p1001": "77c37e99-bf13-4bc5-af95-7c071f5a7115" }, "root_ids": ["p1001"] }];
            root.Bokeh.embed.embed_items(docs_json, render_items);
          }
          if (root.Bokeh !== undefined) {
            embed_document(root);
          } else {
            let attempts = 0;
            const timer = setInterval(function (root) {
              if (root.Bokeh !== undefined) {
                clearInterval(timer);
                embed_document(root);
              } else {
                attempts++;
                if (attempts > 100) {
                  clearInterval(timer);
                  console.log("Bokeh: ERROR: Unable to run BokehJS code because BokehJS library is missing");
                }
              }
            }, 10, root)
          }
        })(window);
      });
    };
    if (document.readyState != "loading") fn();
    else document.addEventListener("DOMContentLoaded", fn);
  })();
</script>


As for the ‘div’ variable, it contains a single HTML <div> tag which holds the component.

HTML




<div id="77c37e99-bf13-4bc5-af95-7c071f5a7115" data-root-id="p1001" style="display: contents;"></div>


Complete Flask App

The above two HTML codes can be utilized with the required Bokeh imports to add the graphs in our Flask apps. Let us see the complete Flask code-named main.py:

Python3




# Importing required functions
from flask import Flask, render_template
from bokeh.embed import components
from bokeh.plotting import figure
  
# Flask constructor
app = Flask(__name__)
  
# Root endpoint
  
  
@app.route('/')
def homepage():
  
    # Defining Chart Data
    language = [
        'Python', 'Java', 'JavaScript', 'C#', 'PHP', 'C/C++',
        'R', 'Objective-C', 'Swift', 'TypeScript', 'Matlab',
        'Kotlin', 'Go', 'Ruby', 'VBA'
    ]
    popularity = [
        31.56, 16.4, 8.38, 6.5, 5.85, 5.8, 4.08, 2.79, 2.35,
        1.92, 1.65, 1.61, 1.44, 1.22, 1.16
    ]
  
    # Creating Plot Figure
    p = figure(
        x_range=language,
        height=400,
        title="Popularity of Programming Languages",
        sizing_mode="stretch_width"
    )
  
    # Defining Plot to be a Vertical Bar Plot
    p.vbar(x=language, top=popularity, width=0.5)
    p.xgrid.grid_line_color = None
    p.y_range.start = 0
  
    # Get Chart Components
    script, div = components(p)
  
    # Return the components to the HTML template
    return render_template(
        template_name_or_list='charts.html',
        script=script,
        div=div,
    )
  
  
# Main Driver Function
if __name__ == '__main__':
    # Run the application on the local development server
    app.run(debug=True)


templates/charts.html

This python file will be the entry point to the Flask application. We will also create an HTML template named ‘charts.html‘ in a ‘templates‘ folder. The flask app will return the plots to this HTML template and through it, we can view the plots. Below is the code for our template:

HTML




<!DOCTYPE html>
<html lang="en">
  
<head>
    <title>Bokeh Charts</title>
</head>
  
<body>
    <h1>Render and Return Plot to View in Flask</h1>
    {{ div | safe }}
    {{ script | safe }}
</body>
  
</html>


To run the above Flask code, we can use the following command (assuming your Flask filename is main.py

python main.py

The Flask app will generate the same chart as discussed earlier and will return an HTML code that embeds the required script and div tags from the Bokeh chart. The output can be viewed on the link http://127.0.0.1:5000/. 

Output:

How to Render and Return Plot to View in Flask

 



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads