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

Conflict with bqplot #369

Open acelere opened 3 years ago

acelere commented 3 years ago

Let me start by saying this library is awesome and thank you for making it available.

There seems to be some conflict between ipyvolume and bqplot.

I am running jupyterhub with dockerspawner and I have one fresh container with ipyvolume and another one without. When I create a bqplot marketmap on the container without, it renders fine: market_map_ok3

But when I run the same code using the container with ipyvolume installed, it fails to display the widget: market_map_not_ok3

The following is a list from pip freeze on each container:

Without ipyvolume With ipyvolume
$ pip freeze $ pip freeze
absl-py==0.11.0 absl-py==0.11.0
aiohttp==3.7.3 aiohttp==3.7.3
alembic==1.5.5 alembic==1.5.5
anyio==2.1.0 anyio==2.1.0
argon2-cffi==20.1.0 argon2-cffi==20.1.0
async-generator==1.10 async-generator==1.10
async-timeout==3.0.1 async-timeout==3.0.1
attrs==20.3.0 attrs==20.3.0
Babel==2.9.0 Babel==2.9.0
backcall==0.2.0 backcall==0.2.0
bleach==3.3.0 bleach==3.3.0
bqplot==0.12.23 bqplot==0.12.23
certifi==2020.12.5 certifi==2020.12.5
certipy==0.1.3 certipy==0.1.3
cffi==1.14.5 cffi==1.14.5
chardet==3.0.4 chardet==3.0.4
click==7.1.2 click==7.1.2
cryptography==3.4.6 cryptography==3.4.6
cvxpy==1.1.10 cvxpy==1.1.10
cycler==0.10.0 cycler==0.10.0
debugpy==1.2.1 debugpy==1.2.1
decorator==4.4.2 decorator==4.4.2
defusedxml==0.6.0 defusedxml==0.6.0
ecos==2.0.7.post1 ecos==2.0.7.post1
entrypoints==0.3 entrypoints==0.3
flatbuffers==1.12 flatbuffers==1.12
future==0.18.2 future==0.18.2
h5py==3.1.0 h5py==3.1.0
idna==2.10 idna==2.10
  ipydatawidgets==4.2.0
ipyfilechooser==0.4.2 ipyfilechooser==0.4.2
ipykernel==5.5.0 ipykernel==5.5.0
ipympl==0.6.3 ipympl==0.6.3
ipython==7.20.0 ipython==7.20.0
ipython-genutils==0.2.0 ipython-genutils==0.2.0
  ipyvolume==0.5.2
  ipywebrtc==0.5.0
ipywidgets==7.6.3 ipywidgets==7.6.3
jax==0.2.9 jax==0.2.9
jaxlib==0.1.61 jaxlib==0.1.61
jedi==0.18.0 jedi==0.18.0
jhsingle-native-proxy==0.7.1 jhsingle-native-proxy==0.7.1
Jinja2==2.11.3 Jinja2==2.11.3
json5==0.9.5 json5==0.9.5
jsonschema==3.2.0 jsonschema==3.2.0
jupyter-client==6.1.11 jupyter-client==6.1.11
jupyter-core==4.7.1 jupyter-core==4.7.1
jupyter-packaging==0.7.12 jupyter-packaging==0.7.12
jupyter-server==1.4.1 jupyter-server==1.4.1
jupyter-telemetry==0.1.0 jupyter-telemetry==0.1.0
jupyterhub==1.3.0 jupyterhub==1.3.0
jupyterlab==3.0.9 jupyterlab==3.0.9
jupyterlab-pygments==0.1.2 jupyterlab-pygments==0.1.2
jupyterlab-server==2.3.0 jupyterlab-server==2.3.0
jupyterlab-widgets==1.0.0 jupyterlab-widgets==1.0.0
kiwisolver==1.3.1 kiwisolver==1.3.1
Mako==1.1.4 Mako==1.1.4
MarkupSafe==1.1.1 MarkupSafe==1.1.1
matplotlib==3.3.4 matplotlib==3.3.4
metakernel==0.27.5 metakernel==0.27.5
mistune==0.8.4 mistune==0.8.4
mpmath==1.2.1 mpmath==1.2.1
multidict==5.1.0 multidict==5.1.0
nbclassic==0.2.6 nbclassic==0.2.6
nbclient==0.5.2 nbclient==0.5.2
nbconvert==6.0.7 nbconvert==6.0.7
nbformat==5.1.2 nbformat==5.1.2
nest-asyncio==1.5.1 nest-asyncio==1.5.1
notebook==6.2.0 notebook==6.2.0
numpy==1.20.1 numpy==1.20.1
oauthlib==3.1.0 oauthlib==3.1.0
octave-kernel==0.32.0 octave-kernel==0.32.0
opt-einsum==3.3.0 opt-einsum==3.3.0
osqp==0.6.2.post0 osqp==0.6.2.post0
packaging==20.9 packaging==20.9
pamela==1.0.0 pamela==1.0.0
pandas==1.2.2 pandas==1.2.2
pandocfilters==1.4.3 pandocfilters==1.4.3
parso==0.8.1 parso==0.8.1
pexpect==4.8.0 pexpect==4.8.0
pickleshare==0.7.5 pickleshare==0.7.5
Pillow==8.1.0 Pillow==8.1.0
prometheus-client==0.9.0 prometheus-client==0.9.0
prompt-toolkit==3.0.16 prompt-toolkit==3.0.16
ptyprocess==0.7.0 ptyprocess==0.7.0
pycparser==2.20 pycparser==2.20
Pygments==2.8.0 Pygments==2.8.0
pyOpenSSL==20.0.1 pyOpenSSL==20.0.1
pyparsing==2.4.7 pyparsing==2.4.7
pyrsistent==0.17.3 pyrsistent==0.17.3
python-dateutil==2.8.1 python-dateutil==2.8.1
python-editor==1.0.4 python-editor==1.0.4
python-json-logger==2.0.1 python-json-logger==2.0.1
  pythreejs==2.2.1
pytz==2021.1 pytz==2021.1
pyzmq==22.0.3 pyzmq==22.0.3
qdldl==0.1.5.post0 qdldl==0.1.5.post0
requests==2.25.1 requests==2.25.1
ruamel.yaml==0.16.12 ruamel.yaml==0.16.12
scikit-aero==0.1 scikit-aero==0.1
scipy==1.6.1 scipy==1.6.1
scs==2.1.2 scs==2.1.2
seaborn==0.11.1 seaborn==0.11.1
Send2Trash==1.5.0 Send2Trash==1.5.0
simpervisor==0.4 simpervisor==0.4
six==1.15.0 six==1.15.0
sniffio==1.2.0 sniffio==1.2.0
SQLAlchemy==1.3.23 SQLAlchemy==1.3.23
sympy==1.7.1 sympy==1.7.1
terminado==0.9.2 terminado==0.9.2
testpath==0.4.4 testpath==0.4.4
torch==1.7.1 torch==1.7.1
torchvision==0.8.2 torchvision==0.8.2
tornado==6.1 tornado==6.1
traitlets==5.0.5 traitlets==5.0.5
traittypes==0.2.1 traittypes==0.2.1
typing-extensions==3.7.4.3 typing-extensions==3.7.4.3
uncertainties==3.1.5 uncertainties==3.1.5
urllib3==1.26.3 urllib3==1.26.3
voila==0.2.7 voila==0.2.7
wcwidth==0.2.5 wcwidth==0.2.5
webencodings==0.5.1 webencodings==0.5.1
widgetsnbextension==3.5.1 widgetsnbextension==3.5.1
xarray==0.16.2 xarray==0.16.2
xeus-python==0.11.1 xeus-python==0.11.1
xlrd==2.0.1 xlrd==2.0.1
yarl==1.6.3 yarl==1.6.3

Perhaps this is linked with bqplot d3 #1245???

This is the notebook code:

#create MarketMap
import pandas as pd
from bqplot.market_map import MarketMap
from ipywidgets import Layout

class ParameterMap:
    def __init__(self, sub_sampled_data, title, map_groups):
        self.sub_sampled_data = sub_sampled_data
        self.map_names = list(self.sub_sampled_data.columns)
        self.map_codes = [i for i in range(len(self.map_names))]
        self.map_groups = []
        for key in map_groups.keys():
            self.map_groups.append(map_groups.get(key))

        self.map = MarketMap(names=self.map_names, groups=self.map_groups,     
                               layout=Layout(min_width='50px', min_height='70px'),
                                 enable_hover=False, cols=3,
                            map_margin={'top':50, 'bottom':0, 'left':0, 'right':25})

        self.map.font_style = {'font-size': '10px', 'fill':'white'}
        self.map.title = title
        self.map.title_style = {'fill': 'Red'}

    def update_map(self, sub_sampled_data, map_groups):
        self.sub_sampled_data = sub_sampled_data
        self.map_names = list(self.sub_sampled_data.columns)
        self.map_codes = [i for i in range(len(self.map_names))]
        self.map_groups = []
        for key in map_groups.keys():
            self.map_groups.append(map_groups.get(key))

        self.map.names = self.map_names
        self.map.groups = self.map_groups

data_label = 'test_dat0'
data_length = 10
test_data = {}
for i in range(data_length):
    test_data[f'{data_label}_{i}'] = [1,2,3,4] 
test_data = pd.DataFrame(test_data)
sub_sampled_data = test_data
map_groups = {}
for p in sub_sampled_data.columns:
    map_groups[p] = 'FTI'
slicemap = ParameterMap(sub_sampled_data, 'Parameter Map', map_groups)
slicemap.map
agoose77 commented 3 years ago

@acelere this is probably because your lab extension version doesn't match the python package version for bqplot. I'm not sure quite why this would happen when installing ipyvolume, because your Python package version for bqplot hasn't changed. However, to confirm that this is the problem, if you run jupyter labextension list, I expect you'll see bqplot with a version that is not 0.5.23

As an aside, it looks like you're using JupyterLab 3. ipyvolume is not yet compatible with JLab3, so it shouldn't work. It might be that if your container is initially configured using conda and then pip was used later, but without further information I'm just guessing here.

Thanks for the nicely formatted pip freeze table. It makes it far easier to compare packages.

acelere commented 3 years ago

Tks for the comments @agoose77

Yes, it is JupyterLab 3... I missed that ipyvolume still does not support that.

In any case, here is the jupyter labextension list

without ipyvolume:

$ jupyter labextension list
JupyterLab v3.0.9
/usr/local/share/jupyter/labextensions
        jupyter-matplotlib v0.8.3 enabled OK
        bqplot v0.5.23 enabled OK
        @jupyter-widgets/jupyterlab-manager v3.0.0 enabled OK (python, jupyterlab_widgets)
        @voila-dashboards/jupyterlab-preview v2.0.1 enabled OK (python, voila)

Other labextensions (built into JupyterLab)
   app dir: /usr/local/share/jupyter/lab
        @jupyterlab/debugger v3.0.7 enabled OK

WITH ipyvolume

with ipyvolume
$ jupyter labextension list
JupyterLab v3.0.9
/usr/local/share/jupyter/labextensions
        jupyter-matplotlib v0.8.3 enabled OK
        bqplot v0.5.23 enabled OK
        jupyterlab-datawidgets v7.0.0 enabled OK
        @jupyter-widgets/jupyterlab-manager v3.0.0 enabled OK (python, jupyterlab_widgets)
        @voila-dashboards/jupyterlab-preview v2.0.1 enabled OK (python, voila)

Other labextensions (built into JupyterLab)
   app dir: /usr/local/share/jupyter/lab
        @jupyterlab/debugger v3.0.7 enabled OK
        jupyter-threejs v2.2.0 enabled OK

Now, oddly enough, if I render the notebook with voila, it shows the widget...notice the "lab" version on the left and the "voila" version on the right... voila_OK

agoose77 commented 3 years ago

Voila side-steps the JupyterLab extension loading process, and uses CDNs instead to load them directly (IIRC). It's wierd that ipyvolume somehow breaks your bqplot registration... I wonder if it is somehow related to the threejs module, which is probably not correctly resolving (more guesswork from me).

I would suggest either

acelere commented 3 years ago

OK. Thanks for having a look into this. I will wait for the JL3 support release... I will leave this open and if anyone would like me to try out different configurations or get logs to help, I am can certainly do that.

dboaretti commented 3 years ago

I would like to add here that ipyvolume does not seem to work for me on Jupyterlab 3.1. After the first default installed pip and lab packages, I tried some combinations but I had no luck.