Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iPython/Jupyter Notebook: How to Embed Interactive Graph Using Desmos API?

I've recently switched from taking notes for my Calculus II course with the pen-and-paper system to using Jupyter (formerly known as iPython) notebooks. What a difference!

Anyway, as someone who learns best through visual presentations, I would really like to embed some interactive Desmos graphs in my notebooks (for anyone who is not familiar with Desmos, it is an incredibly powerful, yet easy-to-use, web-based graphing calculator).

Unfortunately, the iPython/Jupyter notebook security model prevents the execution of JavaScript embedded in Markdown cells. The HTML Sanitization library (Google Caja, I believe) strips any HTML tags and JavaScript code you put into Markdown cells.

According to a note in the security model docs, support for some sort of mechanism for allowing HTML/CSS for notebook theming is planned. But the note makes no mention of JavaScript support.

I realize cross-site scripting is a serious problem and one that is difficult to defend against, but is there really no means to loosen the security constraints for notebook authors? Perhaps in the future it might be possible to add a configuration option to the notebook metadata (which can be edited from within a notebook session) to specify a list of allowable tags.

In the meantime, does anyone know of a work-around, hack, or other method for embedding output from a third-party API using JavaScript in Markdown cells within a notebook?

If one were to print the appropriate HTML and JavaScript code using Python within a Python cell, would that avoid these restrictions? Maybe I should write a Python wrapper for the Desmos API...

like image 865
tommytwoeyes Avatar asked Sep 26 '22 03:09

tommytwoeyes


3 Answers

You can always use an interact from IPython widgets

from IPython.html.widgets import *
import numpy as np
import matplotlib.pyplot as plt
import math

def linear(w,x,b):
    return w*x + b

def logistic(z):
    return 1/(1+math.e**(-z))

def plt_logistic(a, b):
    x = np.linspace(-20,20, 100)
    h = linear(a,x,b)
    y = logistic(h)
    plt.ylim(-5,5)
    plt.xlim(-5,5)
    plt.plot(x,h)
    plt.plot(x,y)
    plt.grid()
    plt.show()

interact(plt_logistic, a = (-10,10,0.1), b = (-10,10,0.1))

enter image description here

like image 181
Lemonov Avatar answered Oct 11 '22 11:10

Lemonov


I think there are several ways to make it

  • use iframe
  • use raw html display, which may need you write some wrapper first to make it reuseable
  • use some 3-party lib: mpld3, plot.js, here is a list
  • use some other type 3-party lib: IPython-Dashboard
like image 39
taotao.li Avatar answered Oct 11 '22 11:10

taotao.li


Here is how to embed Desmos in Jupyter using jp_proxy widgets:

enter image description here

Please see https://github.com/AaronWatters/jp_proxy_widget -- this code is based on the quick start example: https://www.desmos.com/api/v1.2/docs/index.html

like image 2
Aaron Watters Avatar answered Oct 11 '22 13:10

Aaron Watters