Package: notebookjs
notebookJS: seamless JavaScript integration in Python NotebooksnotebookJSenables the execution of custom JavaScript code in Python Notebooks (Jupyter Notebook and Google Colab). This Python library can be useful for implementing and reusing  interactive Data Visualizations in the Notebook environment.notebookJStakes care of downloading and handling Javascript libraries and CSS stylesheets from the web. Furthermore, it supports bidirectional communication between Python and JavaScript. User interactions in HTML/JavaScript can trigger Python callbacks that process data on demand and send the results back to the front-end code.Implementation details inour paper.See ourblog post.InstallTo install, run:pip install notebookjsOr clone this repository and run:python setup.py installAPIThenotebookJSAPI consists of a single method:execute_js. This method executes a javascript function and sets up the infrastructure for bidirectional communication between Python and Javascript using callbacks.execute_js(library_list,main_function,data_dict={},callbacks={},css_list=[],)Parameterslibrary_list : list of str.
List of strings containing either 1) URL to a javascript library, 2) javascript code, 3) javascriptbundle(Plain JS only - No support for ES6 Modules)main_function : str.
Name of the main function to be called. The function will be called with two parameters:
<div_id>, for example "#my_div", and <data_dict>.data_dict : dict.
Dictionary containing the data to be passed to <main_function>callbacks : dict.
Dictionary of the form {<callback_str_id> : <python_function>}. The javascript library can
use callbacks to talk to python.css_list : list of str.
List of strings containing either 1) URL to a CSS stylesheet or 2) CSS stylesMain Functionmain_functionis the javascript function that will be run when execute_js is called. It has the following signature:functionmain_function(div_id,data_dict)Example of Main FunctionAs a simple example, we can use D3 to add a circular div to the output cell:functiondraw_circle(div_id,data){// Function that draws a circle of color <data.color> inside the div <div_id> using D3d3.select(div_id).append("div").style("width","50px").style("height","50px").style("background-color",data.color).style("border-radius","50px")}Callbackscallbackscontains a dictionary that maps an identifier string to a Python function. Data is passed to/from callbacks using json/dicts.For example, the following callback computes the number to the power of 2.defcompute_power_2(data){n=data.nn2=n**2return{"power2":n2}}callbacks={"compute_power_2":compute_power_2}execute_js(...,callbacks=callbacks)In Javascript, we can call this callback with the classCommAPI.CommAPIis automatically injected in the Javascript bynotebookJS.letcomm=newCommAPI("compute_power_2",(ret)=>{alert("The returned value is "+ret.power2)})comm.call({n:3})// An alert will be shown with the message: "The returned value is 9"Jupyter Notebook and Google Colab have different APIs for sending data to/from Javascript/Python.CommAPIabstracts the different APIs in a single convenient class.ExamplesHello World - Python CallbacksIn this example, we show how to display "hello world" in multiple languages using Javascript and Python. The Javascript is responsible for updating the front end and requesting a new message from Python. Python returns a random message every time the callback is invoked.Javascript to update the div with a hello world messagehelloworld_js="""function helloworld(div_id, data){comm = new CommAPI("get_hello", (ret) => {document.querySelector(div_id).textContent = ret.text;});setInterval(() => {comm.call({})}, 1000);comm.call({});}"""Defining the Python Callbackimportrandomdefhello_world_random(data):hello_world_languages=["Ola Mundo",# Portuguese"Hello World",# English"Hola Mundo",# Spanish"Geiá sou Kósme",# Greek"Kon'nichiwa sekai",# Japanese"Hallo Welt",# German"Namaste duniya",# Hindi"Ni hao, shijiè"# Chinese]i=random.randint(0,len(hello_world_languages)-1)return{'text':hello_world_languages[i]}Invoking the function helloworld in notebookfromnotebookjsimportexecute_jsexecute_js(helloworld_js,"helloworld",callbacks={"get_hello":hello_world_random})See thiscolab notebookfor a live demo.Radial Bar Chart - Running D3 code in the NotebookPlotting a Radial Bar Chart with data loaded from Python. Adapted from thisbl.ock.  SeeExamples/3_RadialBarChart.# Loading librariesd3_lib_url="https://d3js.org/d3.v3.min.js"withopen("radial_bar.css","r")asf:radial_bar_css=f.read()withopen("radial_bar_lib.js","r")asf:radial_bar_lib=f.read()# Loading dataimportpandasaspdenergy=pd.read_csv("energy.csv")# Plotting the Radial Bar Chartfromnotebookjsimportexecute_jsexecute_js(library_list=[d3_lib_url,radial_bar_lib],main_function="radial_bar",data_dict=energy.to_dict(orient="records"),css_list=[radial_bar_css])More examplesPlease see theExamples/folder for more examples.ReferenceIf you usenotebookJS, please reference the following work:"Interactive Data Visualization in Jupyter Notebooks. JP Ono, J Freire, CT Silva - Computing in Science & Engineering, 2021"Bibtex:@article{ono2021interactive,
  title={Interactive Data Visualization in Jupyter Notebooks},
  author={Ono, Jorge Piazentin and Freire, Juliana and Silva, Claudio T},
  journal={Computing in Science \& Engineering},
  volume={23},
  number={2},
  pages={99--106},
  year={2021},
  publisher={IEEE}
}