Bokeh plot not rendering in Jupyter Notebook saved to html with inline resources

Hi All,

I’m trying to get Bokeh plots to render in Jupyter Notebooks saved to html output which then need to be viewed without an Internet connection. I’m using inline resources (see below), but when opening the html without an Internet connection the plots don’t render - the message ‘Loading BokehJS…’ appears but nothing else happens. When the connection is restored they do render. Note that within the Jupyter Notebook itself (i.e. before saving to html) the plots always render even without an Internet connection. Any idea what I’m doing wrong? Notebook code as follows:

from bokeh.plotting import Figure, show
from bokeh.io import output_notebook
from bokeh.resources import INLINE
output_notebook(resources=INLINE)
fig = Figure()
fig.circle([1, 2, 3], [3, 2, 1], size=20)
show(fig)

I’m using:
Bokeh v1.3.4
Notebook server v5.2.2
Python 3.5.2

Many thanks.

I can’t reproduce any issue with Bokeh 1.4 and notebook 6.0.1 on OSX. My first suggestion is to try different combinations of versions and systems to try and characterized when/where this occurs with more precision.

Thanks Bryan. I’ll update versions and see what happens.

I upgraded versions but no change, BokehJS doesn’t load in the html output unless there is an active Internet connection. New versions are:

bokeh 1.4.0
jupyter 1.0.0
jupyter_client 5.3.4
jupyter_console 6.0.0
jupyter_core 4.6.1
python 3.7.5

The OS is Ubuntu 16.04.6 64-bit, but I have the same problem running on Windows 10 (albeit with older versions - Bokeh v1.2 and jupyter_console 5.2).

Console package is not really relevant, what version of the notebook package do you have?

From Help->About in the Jupyter Notebook it reports:
Notebook Server: 6.0.1
also IPython 7.9.0 in case that’s relevant.

I had a look at the browser (Firefox 70.0.1) console to see if it contained anything useful. If there’s no Internet connection the following error appears twice:
ReferenceError: is not defined The lines of code referred to are: var element = (’#c9c016cc-97f9-431b-87e2-289bf6465fa1’);
and
var element = $(’#a1447f4c-71ab-4666-b220-e9cac583c875’);
These reappear every time the page is reloaded. Once the Internet connection is restored they disappear.

Sorry, something went wrong with the formatting there: the error was:

ReferenceError: $ is not defined

Something in the saved HTML output is trying to access jQuery via CDN, presumably. But it’s not Bokeh, Bokeh has not used or relied on jQuery for years. This might be a notebook issue or some other extension you are using.

@mateusz do you have any ideas offhand?

Thanks again. I’m not using any extensions I’m aware of. Here are a few lines of code above and below the error in case they’re helpful (as stated before the error occurs at var element = …)

<div class="output_html rendered_html output_subarea ">

    <div class="bk-root">
        <a href="https://bokeh.org" target="_blank" class="bk-logo bk-logo-small bk-logo-notebook"></a>
        <span id="1001">Loading BokehJS ...</span>
    </div>
</div>

</div>

<div class="output_area">

    <div class="prompt"></div>





<div id="c9c016cc-97f9-431b-87e2-289bf6465fa1"></div>
<div class="output_subarea output_javascript ">
<script type="text/javascript">
var element = $('#c9c016cc-97f9-431b-87e2-289bf6465fa1');

(function(root) {
  function now() {
    return new Date();
  }

  var force = true;

  if (typeof root._bokeh_onload_callbacks === "undefined" || force === true) {
    root._bokeh_onload_callbacks = [];
    root._bokeh_is_loading = undefined;
  }

  var JS_MIME_TYPE = 'application/javascript';
  var HTML_MIME_TYPE = 'text/html';
  var EXEC_MIME_TYPE = 'application/vnd.bokehjs_exec.v0+json';
  var CLASS_NAME = 'output_bokeh rendered_html';

  /**
   * Render data to the DOM node
   */
etc.

@Marcus_Donnelly I don’t know where that is coming from. I can’t find that in our codebase:

(base) ❯ grin "var element ="
./_templates/autoload_js.js:
   90 :       var element = document.createElement('script');
  101 :   var element = document.getElementById({{ elementid|json }});

We take alot of care only use e.g. document.getElementById, and not anything like jquery. I also tried checking the notebooks extension repo and could not find anything there either.

How are you exporting these? I just did the HTML export from the File menu. Are you using a separate tool like nbconvert or something?

It looks like this may have been an issue previously on the Jupyter side:

I wonder if it has crept back in.

Thanks @Bryan, perhaps I need to try an earlier version of the notebook in case the jQuery dependency has been reintroduced. In answer to your earlier question I’ve used both HTML export from the File drop-down and nbconvert, and the problem occured with both.

However I’m confused as to why you can’t reproduce the problem, sounds like you were using the same notebook version as me (or close enough). Is there any chance your browser is caching something which allows the plots to keep rendering when you have no Internet connection?

It doesn’t work for me either. My first answer was before I realized that the issue was really actually about the airgap scenario, and not just HTML export in general.

As an added note, look at the very top of the generated HTML output:

<!DOCTYPE html>
<html>
<head><meta charset="utf-8" />

<title>Untitled1</title>

<script src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.1.10/require.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>

That’s not from Bokeh, and definitely assumes a network connection. I think this is probably an issue that will have to be taken up on the Jupyter side.

Thanks for all the help @Bryan. I’ll look into raising an issue on an appropriate Jupyter forum.