widgetti / ipyvolume

3d plotting for Python in the Jupyter notebook based on IPython widgets using WebGL
MIT License
1.94k stars 234 forks source link

broken Jupyter Notebook Output caused by Ipyvolume #109

Open TimoFriedri opened 6 years ago

TimoFriedri commented 6 years ago

Hi,

The function ipyvolume.movie() breaks the output of notebook cells. I assume it is the call of ipywidgets.Output().

I noticed that, when I scripted some gif generation. The new figures have nevert shown up. There is also no print() output afterr the ipyvolume.movie() call.

You also call ipywidgets.Output() in _screenshot_data()

TimoFriedri commented 6 years ago

Update:

I removed all code related to ipywidgets.Ouput() in the functions movie and on_screenshot_data. This changed nothing. Evereything " worked" as before, also the "bug". Somehow the output targeted to "default jupyter cell output area" after calling movie gets lost in nirvana.

BTW: Why do you use ipywidgets.Output() in these functions? I don't the a reason for that.

TimoFriedri commented 6 years ago

Some more Info:

The last output I can see in my output cell after calling movie is the print command in line 714 in pylab.py.

Then all print(), ipywidgets.display(), ipv.figure(), .. are lost somewhere.

The ipywidgets.Output() is supposed to be a context handler, so I don't get why this happens.

TimoFriedri commented 6 years ago

Here is some code to reproduce the behaviour:

import ipyvolume as ipv
import numpy as np
import ipywidgets
from IPython.display import display

x, y, z = np.random.random((3, 100))
kwargs = dict(width=50, height=50)

print('red')
f = ipv.figure(key='red', **kwargs)
ipv.scatter(x, y, z, size=1, marker="sphere")
ipv.show()
ipv.movie('dummy.gif', fps=20, frames=100,)

o1 = ipywidgets.Output()
with o1:
    print('blue')
    ipv.figure(key='blue',**kwargs)
    ipv.scatter(x, y, z, size=1, marker="sphere", color='blue')
    ipv.show()   
display(o1)

print('black')
ipv.figure(key='black',**kwargs)
ipv.scatter(x, y, z, size=1, marker="sphere", color='black')
ipv.show()

print('end')

I only see the red plot, the black and the blue will not be shown. Remove the movie call and all plots are shown!

maartenbreddels commented 6 years ago

I use the output widget to make sure the print output goes somewhere. The issue is that if code is being executed as the result of an event from the browser (as with the screenshots), the output of say print has no natural way to go, there are quite some discussions going on on the ipywidget project on this. But, the annoying part is that the Output widget seems to have some issues with some versions of Jupyterlab or jupyter-widget. Now with the beta of Jupiter lab out, I should take a look at this. Hope to take a look tomorrow or the day after!

TimoFriedri commented 6 years ago

Hi,

It hasn't worked for me in jupyter notebook and neither now in jupyter lab: FYI my versions of maybe relevant packages:

# Name                    Version                   Build  Channel
_nb_ext_conf              0.4.0                    py36_1  
ipykernel                 4.8.2                    py36_0  
ipython                   6.2.1            py36h88c514a_1  
ipython_genutils          0.2.0            py36hb52b0d5_0  
ipyvolume                 0.4.5                    py36_0    conda-forge
ipywebrtc                 0.3.0                    py36_0    conda-forge
ipywidgets                7.1.2                    py36_0  
jupyter                   1.0.0                    py36_4  
jupyter_client            5.2.2                    py36_0  
jupyter_console           5.2.0            py36he59e554_1  
jupyter_contrib_core      0.3.3                    py36_0    conda-forge
jupyter_contrib_nbextensions 0.4.0                    py36_0    conda-forge
jupyter_core              4.4.0            py36h7c827e3_0  
jupyter_highlight_selected_word 0.1.0                    py36_0    conda-forge
jupyter_latex_envs        1.3.8.2                  py36_1    conda-forge
jupyter_nbextensions_configurator 0.4.0                    py36_0    conda-forge
jupyterlab                0.31.8                   py36_0  
jupyterlab_launcher       0.10.2                   py36_0  
jupyterthemes             0.18.3                     py_0    conda-forge
nb_anacondacloud          1.4.0                    py36_0  
nb_conda                  2.2.1            py36h8118bb2_0  
nb_conda_kernels          2.1.0                    py36_0  
nbconvert                 5.3.1            py36hb41ffb7_0  
nbformat                  4.4.0            py36h31c9010_0  
nbpresent                 3.0.2            py36h5f95a39_1  
nodejs                    8.9.3                h439df22_0  
python                    3.6.4                hc3d631a_1  
widgetsnbextension        3.1.4                    py36_0  
maartenbreddels commented 6 years ago

Ok, basically, after you call screenshot or movie, the output goes nowhere anymore, so there are a few options: Don't directly call ipv.movie(), do it in the next cell, or.

output = widget.Output()
display(output) # make sure this goes into the current cell
ipv.screenshot() # or ipv.movie()
with output:
  .... # the rest

I don't see how this can be fixed for python2, in Python 3, and if ipywidgets will have some async options or if https://github.com/jupyter-widgets/ipywidgets/issues/1648 gets resolved. I'll keep this open, and hopefully you can work around it with this info, and I hope to fix it in the future.

TimoFriedri commented 6 years ago

Hi,

unfortunately your workaround suggestion with output does not help in my case. Try this code and only the first plot will be shown, despite explicit output calls.

import ipyvolume as ipv
import numpy as np
import ipywidgets
from IPython.display import display

o = ipywidgets.Output()
display(o)

x, y, z = np.random.random((3, 100))
kwargs = dict(width=50, height=50)

with o:
    print('red')
    f = ipv.figure(key='red', **kwargs)
    ipv.scatter(x, y, z, size=1, marker="sphere")
    ipv.show()
ipv.movie('dummy.gif', fps=20, frames=100,)

with o:
    print('blue')
    ipv.figure(key='blue',**kwargs)
    ipv.scatter(x, y, z, size=1, marker="sphere", color='blue')
    ipv.show()   

print('end')
TimoFriedri commented 4 years ago

Hi, any update on this issue? I just ran again into this problem with the savefig() function. The output widgets suggestions is still not really a solution. I tried it with version 0.6.0a2.

maartenbreddels commented 4 years ago

As expected and described above, it gives me this output: image

After a call to movie, you can only use the output widget, all other output will go nowhere, so I don't expect end to be printed (unfortunately). In jupyter lab there is a special log where this goes btw, an icons on the bottom left will open it.