Mathjs and newer version of D3 not working in the Notebook

479 views
Skip to first unread message

mcmc...@unca.edu

unread,
Feb 24, 2017, 9:56:50 PM2/24/17
to Project Jupyter
I've been playing with Javascript in the Jupyter notebook following Brian Coffey's excellent D3 tutorial here:
https://github.com/stitchfix/d3-jupyter-tutorial

It appears, though, that more recent versions of D3 no longer work. Specifically, it seems that a problem developed at the switch from version 3 of D3 to version 4 of D3. You can try the following, for example:

from IPython.core.display import HTML
#HTML('<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.js"></script>')
#HTML('<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.0.0/d3.js"></script>')

Of course, you need to uncomment the line that loads the verision of D3 you want to try. The first version, V3.5.17 of D3, works great. The second one, V4.0.0 of D3, doesn't work; more specifically, the `d3` object never makes it into the global namespace. Even more specifically, the Javascript console in Firefox indicates that there is a
"Mismatched anonymous define() module: [object Object]
http://requirejs.org/docs/errors.html#mismatch"
Having a look at RequireJS, it looks like my version of the notebook is running Version 2.1.22 of RequireJS, which is a bit behind the times, I think. Perhaps that's related to the issue; I really don't know, but I don't think it's likely that D3 has been misusing Require since V4 came out.

I don't think this issue is specific to D3. In fact, I'd happily work with d3.v3. My real issue is with mathjs, which I can't get to work at all: http://mathjs.org/


I'm running Anaconda version 4.3.1 and ran 'conda update notebook' hoping that might help.


mcmc...@unca.edu

unread,
Mar 15, 2017, 9:33:22 AM3/15/17
to Project Jupyter
Since my original post didn't receive any response, I thought I'd illustrate the type of thing that I'm trying to accomplish. The general idea, of course, is to mix Python and Javascript in the Jupyter notebook. In this way, output generated by Python can be made interactive using Javascript. There are lots of possibilities; a few examples are included in Brian Coffey's tutorial that I linked to in my first post.

I've got a few things I've generated myself along these lines but the first thing I'm somewhat happy with involves the dynamic illustration of an orbit on top of a Julia set generated with Python. You can see the result here:
http://marksmath.org/visualization/InteractiveBasinsInJupyter/

One thing that's nice about this approach is that the interactivity is maintained and active in the exported HTML version. Thus, if you scroll down to one of the images in that webpage and hover your mouse over that image, you should see an orbit that's updated dynamically as you move the mouse. If you want the full blown Jupyter notebook together with the ancillary code, you can grab that too:
http://marksmath.org/visualization/InteractiveBasinsInJupyter.zip


While I'm somewhat happy with this, the question remains - why won't MathJS and newer versions of D3 load into the notebook? It there a way to get around this limitation?

It's pretty easy to test when a library has loaded - simply call an alert on any object exported from the library to the global namespace. For example, here's how to (try to) load D3:

from IPython.core.display import HTML

In a separate cell, you can then do:

HTML("<script>alert(d3)</script>")


You should get an alert box that says [object Object], since d3 is an object, but you don't. It works fine with the older version of D3, just change the 4.0.0 to 3.5.17.

The same problem happens with MathJS. As a result, I ended up writing my own little complex class for this example including polynomial evaluation with Horner's method. Not that big deal for this example, but MathJS includes a lot of functionality that might be nice to incorporate for these types of examples. It also includes a parser that would make it very easy to translate mathematical expressions from Python to Javascript.

Min RK

unread,
Mar 16, 2017, 12:01:56 PM3/16/17
to Project Jupyter

Sorry for the silence!

d3 v4 must be loaded with require, e.g.

require(['d3'], function (d3) {
    d3.....
})

So each output should have a require call like this.

You can tell require where to get d3 with:

require.config({
  paths: {
    d3: "https://d3js.org/d3.v4.min"
  }
});

which you will need to do one time, before require('d3') will work.

reference

example notebook

-Min

Reply all
Reply to author
Forward
0 new messages