Django Embed Bokeh Graph using json_item()

Hi Everyone,

I’m posting an example here that can be used inside the bokeh documentation as well that outlines how to use bokeh inside of django without using a bokeh server. Essentially one can use the json_item() functionality to be able to embed graphs. I find json_item to be very fast and flexible and versatile as one can use ajax calls to update the graphs as I am doing and need to do and even connect it to external third party widgets like an ionrangeslider to do even more fancy things like use the ionrange slider to update the graph content.

I am using bokeh 1.4.0 and django 2.2.Note I am not going through the django installation setup in total. I assume one knows how to do it as you only need to follow the django tutorial to do the basic setup. I will post the views, urls and html code you need to get this to work. I will be using django classes and I hope people can use this example. I also hope this example can be embedded and added to the bokeh documentation as it is simple and effective and can be used as is.

urls.py

path('overview/yearly', 
     views.OverviewYearlyView.as_view(), 
     name='overview-yearly'),

views.py

import numpy as np
from bokeh.plotting import figure
from bokeh.layouts import layout
from bokeh.embed import json_item
import json

class OverviewYearlyView(TemplateView):

    template_name = 'dashboard/ok.html'

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)

        # create an example graph
        Fs = 8000
        f = 5
        sample = 8000
        x = np.arange(sample)
        y = np.sin(2 * np.pi * f * x / Fs)

        # here you can customize individual components of a graph property
        plot = figure( x_axis_label='xaxis', plot_width=200, plot_height=200)
        plot.line(x,y, line_width=2, color='darkred')
        plot.toolbar.logo = None
        plot.background_fill_color = "black"
        plot.border_fill_color = "black"
        plot.outline_line_width = 1
        plot.outline_line_color = "#00bfff"
        plot.title.text_color = "#00bfff"
        plot.xaxis.axis_line_color = "#00bfff"
        plot.yaxis.axis_line_color = "#00bfff"
        plot.yaxis.major_label_text_color = "#00bfff"
        plot.xaxis.major_label_text_color = "#00bfff"
        plot.xgrid.grid_line_color = "#00bfff"
        plot.ygrid.grid_line_color = "#00bfff"

        # adjust the layout
        plot_l = layout([plot], sizing_mode='stretch_width')

        #create json item of graphs
        json_plot = json_item(plot_l, 'myplot') 

        # convert dict to string
        stringplot = json.dumps(json_plot)
        context.update({'plot_l':stringplot})
        return context

ok.html

<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">

  <script src="https://cdn.pydata.org/bokeh/release/bokeh-1.4.0.min.js"></script>
  <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
  <script>
    // embed the graph into the html div element
    $(document).ready(function() {
      Bokeh.embed.embed_item({{plot_l|safe}});
    });
  </script> 
</head>

<body>
  <p> Graph below </p>
  <div id="myplot"></div>
</body>

</html>

Now the result of this on your webpage should be this:

and thats it. You can also do AJAX calls and more complex stuff with this hope this helps let me know.

1 Like

That looks really interesting - do you have an example of code where you can update a chart without needing to use a bokeh server

Yes I do as I am doing that for my own project.
In my case to update a chart i can do an ajax call. Essentially on the html side i run a javascript ajax function which calls my django view function which calls a rest api/webservice. The view runs a request object and gets updated data and return back a jsonobject with a new graph object. on the success() function of the ajax call ie the output I just update the graph and i’m done I can post some code for you if you want of my ajax function I’m using that I hope helps you.

I know that an ajax call can be placed into a timer so then you can call your ajax function on a timer every x seconds, minute or hours.