root-project / jsroot

JavaScript ROOT
MIT License
187 stars 80 forks source link

jsroot and JupyterLab #166

Closed wgseligman closed 3 years ago

wgseligman commented 6 years ago

I have no problems using jsroot in jupyter. I have no problems making plots in general in jupyter or jupyterlab. But when I use jsroot in python within JupyterLab; e.g.

import ROOT
%jsroot on
canvas = ROOT.TCanvas()
test = ROOT.TH1D("example","example",100,-5.,5.)
test.FillRandom("gaus",100000)
test.Draw()
canvas.Draw()

or in the ROOT C++ kernel, e.g.,

%jsroot on
TCanvas my_canvas("canvas","canvas title",800,600);
TH1D example("example","example histogram",100,-3,3);
example.FillRandom("gaus",10000);
example.Draw();
my_canvas.Draw();

I just see a blank area in the output that's the same size of the plot I expect. If I turn %jsroot off in both the above examples, the plot is produced. If I use the same notebooks in "plain old jupyter", the plots appear with %jsroot on.

I've tried this on two different machines/OSes with the same results: OS - CentOS 7 Python version - 3.6.5 ROOT version - 6.14.02

OS - Mac OS 10.11.6 Python version - 3.6.6 ROOT version - 6.14.00

Any ideas?

linev commented 6 years ago

Can you check message in browser console? And probably @etejedor can help you more.

etejedor commented 6 years ago

The JSROOT graphics have not yet been integrated with JupyterLab (which is still in beta version until beginning of next year). It is also in the plans of the SWAN notebook service at CERN to work on the integration with JupyterLab, but this effort has not started yet. Any contribution is of course welcome - it would be a matter of checking what has changed in the IPython / Jupyter API for what concerns the rendering of JavaScript graphics.

wgseligman commented 6 years ago

At least I now know that this isn't an error on my part. Thanks!

And now that @etejedor provided the clue, I see why I didn't find out about this on my own: I was searching for issues with JSROOT and JupyterLab. If I had searched for JavaScript and JupyterLab, I would have seen that this is an acknowledged issue.

DraTeots commented 5 years ago

First, to make it work in jupyterlab, there is a workaround. Add the next code in a cell before:

%%javascript
if (!requirejs) {
    var s = document.createElement('script');
    s.src='https://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.6/require.min.js';
    document.body.appendChild(s);
}

It solves the problem.

linev commented 5 years ago

It solves the problem.

But require.js alone does not help.

JSROOT with Jupyter Notebooks was reusing different modules (d3, jquery, jquery-ui) which were registered to require.js in advance. If none of such modules provided with jupyterlab, there should be no any advantage of loading or not loading require.js.

Probably, there is simple fix in the code around creation of JSROOT graphics to avoid require statement at all. I guess, it is here:

https://github.com/root-project/root/blob/master/bindings/pyroot/JupyROOT/helpers/utils.py#L51-L63

One can avoid use of require syntax there completely.

DraTeots commented 5 years ago

Yes! That particular lines gave me a hint of the hack above.

And yes! We (users) are patiently waiting when it will be changed there. And the right jupyterlab extension is developed (which is the proposed way to go for jupyterlab now) too.

Btw I tried to write the extension but get stumbled a bit on what exactly is exported from jsroot modules

etejedor commented 5 years ago

Just to add another piece of information to this conversation, in July we will have a summer student in the ROOT team that will work on the integration of ROOT JS graphics and GUI in JupyterLab.

DraTeots commented 5 years ago

Great news!

Actually, I'm from Electron Ion Collider software consortium (particularly from Jefferson Lab) . We are going to try to use JupyterLab as an entry point for new (and not only) users for our simulation and reconstruction software. The idea, is to provide the simulation environment (with ROOT, Geant, our packets) with jupyterlab as UI on top of it. With features, like make it deployable on cloud platforms, etc.

So we started to write some jupyterlab extensions like x-root mime renderers. This could be a good collaboration point, when the student will arrive. We also have some forces. So we could join the effort.

Just in case, my email romanov@jlab.org

etejedor commented 5 years ago

Hi Dimtry, in the ROOT team we are in close contact with EIC colleagues, in particular with Markus Diefenthaler. In fact, one of our team members, Lorenzo Moneta, is attend the EIC Software Meeting next week and will give a talk about ROOT.

I also wanted to point out that at CERN we have the SWAN service (https://swan.cern.ch), which provides a Jupyter notebook interface on top of CVMFS (software) and EOS (data). This is a presentation of the service at the Jupytercon: https://conferences.oreilly.com/jupyter/jup-ny/public/schedule/detail/68359 We are planning to migrate the classic Jupyter interface to Jupyterlab.

There is also a version of SWAN that is installable on premises, called ScienceBox: https://sciencebox.web.cern.ch/sciencebox/

diocas commented 5 years ago

Let me just add that the SWAN/CERNBox versions you see in ScienceBox are old compared to what we have in production at CERN. But, if you switch to the uboxed/kuboxed branch called "update_sciencebox", you will get the latest stuff. This will be merged in the near future, but for now it's still missing some documentation to be ready. If you are interested in trying and have any doubt, please let us know.

linev commented 5 years ago

I reopen this issue - seems to be there is interest to have it running. There is also related Jira issue https://sft.its.cern.ch/jira/browse/ROOT-10116

wgseligman commented 5 years ago

First, to make it work in jupyterlab, there is a workaround. Add the next code in a cell before:

%%javascript
if (!requirejs) {
    var s = document.createElement('script');
    s.src='https://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.6/require.min.js';
    document.body.appendChild(s);
}

It solves the problem.

Thanks DraTeots, but I'm afraid this did not solve the problem for me. I get the error that 'requirejs' is undefined. I fiddled with installing the require.js package with npm, but that didn't change anything.

Based on the other comments I see in this thread, I think the underlying issue is that I don't understand how javascript+jupyterlab work together. Iinstructions like yours assume that I'll know what to do if some js component is missing. Clearly I don't!

As a side note, the work I'm doing is part of a jupyterhub installation that's used by a couple of dozen people. So any solution with jsroot in jupyterlab has to work transparently for all the users. If they have to execute special cells to make jsroot work, then they simply won't use jsroot, jupyterlab, or both.

DraTeots commented 5 years ago

@etejedor The world is small! We are on the same team with Markus, our offices are next to each other. During the very same conference, the next week on Tuesday I will give a presentation of our prototype.

@wgseligman Yes, unfortunately loading modules in Javascript became convoluted. Historically there where no "import" command in javascript so many solutions where developed to solve it. Because of this and other needs, large projects have pretty nontransparent build systems in JS, which require even more learning than, say, cmake for C++. Each solution has PROC and CONS and it is the part, that has been changed in jupyterlab.

In general, when you install something with npm it gets installed on server side. It then should get its way to your browser one way or another. The best solution would be just fixing it on ROOT side, I guess.

DraTeots commented 5 years ago

Hi All!

On that EIC software meeting I actually showed a jupyter lab extension, that can render root files and geometry inside jupyter lab. Initially the extension used iframe, which is simple, but has too many limitations. Rewriting this to directly use jsroot API got me to stack with something similar to #165

The thing I don't really like in the solution of #165 is that it looks more like workaround. The Githubissues.

  • Githubissues is a development platform for aggregating issues.