I was wondering how ipywidgets use the display machinery of IPython to display itself. SinceI couldn't find any use of _repr_html, I was puzzled. Also I wanted to understand how create an object composed of various widgets that can display itself.

Answer came from ipython/Custom Display Logic.ipynb at 40c34d3369c3d271149e13ac07f1bd2f5a716635 · ipython/ipython.

example of using _ipython_display_ to display HTML and JS


In [95]:
import json
import uuid
from IPython.display import display_javascript, display_html, display

class FlotPlot(object):
    def __init__(self, x, y):
        self.x = x
        self.y = y
        self.uuid = str(uuid.uuid4())
    
    def _ipython_display_(self):
        json_data = json.dumps(list(zip(self.x, self.y)))
        display_html('<div id="{}" style="height: 300px; width:80%;"></div>'.format(self.uuid),
            raw=True
        )
        display_javascript("""
        require(["//cdnjs.cloudflare.com/ajax/libs/flot/0.8.2/jquery.flot.min.js"], function() {
          var line = JSON.parse("%s");
          console.log(line);
          $.plot("#%s", [line]);
        });
        """ % (json_data, self.uuid), raw=True)

In [96]:
import numpy as np
x = np.linspace(0,10)
y = np.sin(x)
FlotPlot(x, np.sin(x))


simple compound widget


In [97]:
from ipywidgets import (widgets, VBox, HBox)
from IPython.display import display, display_html, display_javascript
import traitlets

class SimpleCompoundWidget(object):
    def __init__(self, init_value=''):
        self.text_w = widgets.Text(value=init_value)
        self.mirror_w = widgets.HTML(value="<b>{}</b>".format(init_value))
        self.vbox = VBox([self.text_w, self.mirror_w])
        
        self.text_w.observe(self.handle_text_change, names='value')
    
    def handle_text_change(self, change):
        #print (change)
        self.mirror_w.value = "<b>{}</b>".format(change['new'])
    
    def _ipython_display_(self):
        display(self.vbox)
        
    def __del__(self):
        """
        this doesn't quite work with del s
        """
        self.text_w.close()
        self.mirror_w.close()
        self.vbox.close()

In [98]:
s = SimpleCompoundWidget("hello")
s

In [99]:
# del s doesn't do the job (for some reason) but calling s.__del__() works
s.__del__()

In [ ]: