Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Is it possible to use ipympl - %matplotlib widget in jupyter-ui? #85

Open
BrandonEscamilla opened this issue Aug 8, 2023 · 29 comments
Open
Labels
discuss question Further information is requested

Comments

@BrandonEscamilla
Copy link
Contributor

I am attempting to achieve dynamic plotting using Jupyter-UI. I have followed the steps to install ipympl on my server, and it works fine with the UI version of Jupyter. However, when using Jupyter-UI, I encountered the following error. In the image below you can also find the way I am trying to plot by including %matplotlib widget.

CleanShot 2023-08-08 at 15 01 33

Error:

Open Browser Console for more detailed log - Double click to close this message]
Failed to load model class 'MPLCanvasModel' from module 'jupyter-matplotlib'
Error: Requirejs is needed, please ensure it is loaded on the page.
    at IPyWidgetsClassicManager.requireLoader [as loader] (webpack-internal:///(app-pages-browser)/./node_modules/@jupyter-widgets/html-manager/lib/libembed-amd.js:67:15)
    at eval (webpack-internal:///(app-pages-browser)/./node_modules/@jupyter-widgets/html-manager/lib/htmlmanager.js:105:30)
    at new Promise ()
    at IPyWidgetsClassicManager.loadClass (webpack-internal:///(app-pages-browser)/./node_modules/@jupyter-widgets/html-manager/lib/htmlmanager.js:94:16)
    at IPyWidgetsClassicManager.loadClass (webpack-internal:///(app-pages-browser)/./node_modules/@datalayer/jupyter-react/lib/jupyter/ipywidgets/IPyWidgetsClassicManager.js:64:26)
    at IPyWidgetsClassicManager.loadModelClass (webpack-internal:///(app-pages-browser)/./node_modules/@jupyter-widgets/base-manager/lib/manager-base.js:585:34)
    at IPyWidgetsClassicManager._make_model (webpack-internal:///(app-pages-browser)/./node_modules/@jupyter-widgets/base-manager/lib/manager-base.js:417:36)
    at IPyWidgetsClassicManager.new_model (webpack-internal:///(app-pages-browser)/./node_modules/@jupyter-widgets/base-manager/lib/manager-base.js:260:35)
    at IPyWidgetsClassicManager.handle_comm_open (webpack-internal:///(app-pages-browser)/./node_modules/@jupyter-widgets/base-manager/lib/manager-base.js:170:21)
    at eval (webpack-internal:///(app-pages-browser)/./node_modules/@datalayer/jupyter-react/lib/jupyter/ipywidgets/IPyWidgetsClassicManager.js:36:22)
    at KernelConnection._handleCommOpen (webpack-internal:///(app-pages-browser)/./node_modules/@jupyterlab/services/lib/kernel/default.js:1119:19)
    at async KernelConnection._handleMessage (webpack-internal:///(app-pages-browser)/./node_modules/@jupyterlab/services/lib/kernel/default.js:1287:25)
@echarles
Copy link
Member

echarles commented Aug 9, 2023

Error: Requirejs is needed, please ensure it is loaded on the page.

You probably miss the require.js script in you html page.

<script src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.4/require.min.js"></script>

But even with that, on my env, I hit TypeError: Cannot read properties of undefined (reading 'MPLCanvasModel') which is somehow related to matplotlib/ipympl#460 (see also VS Code being impacted on microsoft/vscode-jupyter#13150).

I am working on the ipywidgets stuff and hopefully will come soon with a fix for this and someting more robust in general for ipwidgets.

@BrandonEscamilla
Copy link
Contributor Author

Yes, in fact, I am trying now with require.js loaded and getting the same error you mentioned. The links you provided mostly address resolving the issue within the Jupyter server UI. Curiously, when I run a notebook from the server UI, I am able to use %matplotlib widget without any problems. However, when integrating it with my Next.js application, it doesn't seem to work. Is there a solution or workaround available to resolve this issue?

@echarles
Copy link
Member

echarles commented Aug 9, 2023

Curiously, when I run a notebook from the server UI, I am able to use %matplotlib widget without any problems

Are you saying you can use %matplotlib widget from the React.js components? Or is it from the vanilla JupyerLab and failing with React.js (including Next.js)?

@BrandonEscamilla
Copy link
Contributor Author

Yes, exactly, it works with the predefined UI that comes with JupyterLab but not working with my next.js app using jupyter-ui.

@echarles
Copy link
Member

I have just pushed work around ipywidget with support for jupyter-matplotlib. I will now make it configurable so anyone can define the widgets he wants, but in the meantime, jupyter-matplotlib is supported out-of-the box in main branch. If it does not show up at the first time, hit run again, looking forward your feedbacks on how it work on your env.

Untitled6

@echarles
Copy link
Member

The latest push introduces a externalIPyWidgets (name can be better) where you can give an array of ipywidgets to load, eg.(see the example in the main tree)

      externalIPyWidgets={["jupyter-matplotlib:0.11.3"]}
      externalIPyWidgets={["bqplot:0.5.42"]}
      externalIPyWidgets={["@widgetti/jupyter-react:0.3.0"]}

cdn.jsdelivr.net may be slow to load the first time, so if it fails at first load, reload your browser and it should work fine.

@echarles
Copy link
Member

Now you have in latest main externalIPyWidgets. and bundledIPyWidgets props with more typed object to pass. External will load from CDN, you have to ship in your package.json what you list in the bundled prop.

@echarles
Copy link
Member

Closing this as resolved, please open separated issue for any specific question.

@BrandonEscamilla
Copy link
Contributor Author

Thank you for your response, @echarles. I have a quick question: Will this update be included in the next release to npm? I'm currently using the npm version, not a local one. Thank you in advance!

@echarles
Copy link
Member

@BrandonEscamilla just published @datalayer/jupyter-react 0.6.2.

this morning I have pushed a feature to ensure that the JupyterLab CSS were not loaded when the components are used in JupyterLab it self 👍

This has driven a small regression for the ipympl widget which was showing correctly before, but now show with the toolbar being move to the bottom. The other ipywidgets (bqplot...) does seem to be impacted.

Also I notice regularly that the widget is not lodaded when you use it quickly after the first time - Maybe time is needed to load the remote javascript, still need to makes sens of what is going on, your feedbacks would be useful there.

Screenshot 2023-08-21 at 12 39 14

@BrandonEscamilla
Copy link
Contributor Author

Hi @echarles, I just tried the new version and it seems it's not working on my project, I already tried including externalIPyWidgets={["jupyter-matplotlib:0.11.3"]} in the Notebook component, and reloading the browser, but not working, is there anything I am probably missing? Thanks!

@echarles
Copy link
Member

@BrandonEscamilla Sorry, forgot to mention that I changed to more typed props (separate the name and version as name: "jupyter-matplotlib", version: "0.11.3" }

For externals

externalIPyWidgets={[
{ name: "bqplot", version: "0.5.42" }
]}

for bundled

bundledIPyWidgets={[
{ name: "jupyter-matplotlib", version: "0.11.3", module: require("jupyter-matplotlib")}
]}

@BrandonEscamilla
Copy link
Contributor Author

Hey @echarles, I'm currently testing this and unfortunately, I haven't been able to make it work. I'm still encountering the same error. Do you have any suggestions? Here's how I included the widget:

CleanShot 2023-08-22 at 14 23 09

This is the error:

CleanShot 2023-08-22 at 14 22 05

Apart from this, I am wondering what's the difference between externalIPyWidget and Bundled? Thanks in advance!

@echarles
Copy link
Member

Rested on my env and it works for me. Now trying to create a codesandbox, but a bit slow atm. Can you double check the version of jupyter-react you use?

Apart from this, I am wondering what's the difference between externalIPyWidget and Bundled? Thanks in advance!

If you add jupyter-matplotlib as a dependency to your project, better to use bundledIPyWidgets, otherwise, you can add any other widgets that is not declared in your package.json, jupyter-react will download it from a CDN (hence the need to declare a externalIPyWidgets. prop).

@BrandonEscamilla
Copy link
Contributor Author

Ok, it seems is working with the bundle. I did npm i jupyter-matplotlib and included the widget through the bundle and it's working. However, as mentioned earlier, the only remaining issue is the toolbar being moved to the bottom. Are there any solutions available to resolve this matter?

@BrandonEscamilla
Copy link
Contributor Author

Well, it seems there is an issue, if you try to change the notebook path while using bundledIPyWidgets, the notebook gets broken. The following error renders:

Oops, something went wrong.

Cannot read properties of undefined (reading 'register')

In the console the following errors appears:

CleanShot 2023-08-22 at 16 10 05

@echarles
Copy link
Member

A few issues here:

@echarles
Copy link
Member

Reopening and will work on that soon.

@echarles echarles reopened this Aug 22, 2023
@echarles
Copy link
Member

@BrandonEscamilla I have release 0.6.3 which brings a more rock-solid ipywidgets support (It now runs fine from the first start). I still have to fix the specific toolbar issue for ipympl but otherwirse, the other widgets I have tests (bqplot, ipyreact, plotly, bokeh) work great.

If you have cycles to look at the toolbar which I think could be a CSS to inject, that would be great. Otherwse, tell me.

@echarles
Copy link
Member

I have released 0.6.3

Sorry, was meaning 0.6.4

@echarles
Copy link
Member

Just released 0.6.5

I have updated the Matplotlib example to load the css from directly and disable the loading by the jupyter content. This fixes the CSS issue. For the path change, with the last release, the component does not throw an error, but after the change, the ipywidgets are not working anymore. I will wait a bit more on @BrandonEscamilla feedback before tackling that remaining issue.

import '@lumino/widgets/style/index.css';
import '@lumino/dragdrop/style/index.css';
import '@jupyterlab/apputils/style/base.css';
import '@jupyterlab/rendermime/style/base.css';
import '@jupyterlab/codeeditor/style/base.css';
import '@jupyterlab/documentsearch/style/base.css';
import '@jupyterlab/outputarea/style/base.css';
import '@jupyterlab/console/style/base.css';
import '@jupyterlab/completer/style/base.css';
import '@jupyterlab/codemirror/style/base.css';
import '@jupyterlab/codeeditor/style/base.css';
import '@jupyterlab/cells/style/base.css';
import '@jupyterlab/notebook/style/base.css';
import '@jupyterlab/filebrowser/style/base.css';
import '@jupyterlab/terminal/style/index.css';
import '@jupyterlab/theme-light-extension/style/theme.css';
import '@jupyterlab/theme-light-extension/style/variables.css';
import '@jupyterlab/ui-components/style/base.css';
import '@jupyter-widgets/base/css/index.css';
import '@jupyter-widgets/controls/css/widgets-base.css';
import "./../../style/index.css";
const Matplotlib = () => (
<Jupyter disableCssLoading={true}>
<Notebook
nbformat={notebook as INotebookContent}
uid="notebook-matplotlib-uid"
bundledIPyWidgets={[
{ name: "jupyter-matplotlib", version: "0.11.3", module: require("jupyter-matplotlib")}
]}
height='calc(100vh - 2.6rem)' // (Height - Toolbar Height).
cellSidebarMargin={120}
CellSidebar={CellSidebarDefault}
Toolbar={NotebookToolbar}
/>
</Jupyter>
)

@BrandonEscamilla
Copy link
Contributor Author

Hey @echarles, I've been experimenting with version 0.6.4 of the library. It appears that loading the CSS and using disableCssLoading={true} option works as intended. Also, as you mentioned, when I modify the file path, the widget stops functioning. So, to address the CSS issue, do I still need to manually load the CSS file, or will the library handle it internally? Thanks in advance!

@echarles
Copy link
Member

to address the CSS issue, do I still need to manually load the CSS file, or will the library handle it internally?

JupyterLab is notably poor with it CSS management (no css-in-js, no css modules, just plain good-old css). I opened PR to fix some of the glitches which got merged, but still experience side effect mainly depending on the order of loading. So for now, the core jupyter-react library does its best to load as it should, but if we want the components to be usable in jupyerlab with non-double css loading, the developer would need to do something like in the Matplotlib example in some case. Is that a stopper for you? I can think a bit more based on your inputs.

when I modify the file path, the widget stops functioning

Yeah, I can fix that next week.

@BrandonEscamilla
Copy link
Contributor Author

Hey @echarles, got it, I think in my case is not a problem to include css in the component directly. I would probably import it through globals.css or something like this, just to avoid having all of the imports there. But I think going into that direction is not a big problem. By the way, now that we are talking about css, are there plans to support dark mode? Or if I wanted to modify the css to support it, where should I look? Thanks in advance!

@echarles
Copy link
Member

I would probably import it through globals.css

You may have the toolbar issue if you load all the css files from an external globals.css file, to be tested on your env.

But I think going into that direction is not a big problem.

Sounds good.

By the way, now that we are talking about css, are there plans to support dark mode?

With #67 I am preparing a more flexiable way to create the notebook with any jupyterlab extension support, including any themes, so dark theme also. We plan also to wrap something for the theme in that folder https://github.com/datalayer/jupyter-ui/tree/933d7acf57fb125a154cbb1be69bdce00cecdec9/packages/theme but it will be for after.

Or if I wanted to modify the css to support it, where should I look? Thanks in advance!

For now, as you will load the css your self, you can try change theme-light-extension with theme-dark-extension in those lines, but not sure of the visual result.

import '@jupyterlab/theme-light-extension/style/theme.css';
import '@jupyterlab/theme-light-extension/style/variables.css';

@BrandonEscamilla
Copy link
Contributor Author

You may have the toolbar issue if you load all the css files from an external globals.css file, to be tested on your env.

I will try this, let you know what happens.

For now, as you will load the css your self, you can try change theme-light-extension with theme-dark-extension in those lines, but not sure of the visual result.

Yeah, I tried already and I think it's not working still showing the light version, I will check if I can do a workaround.

Thanks!

@echarles
Copy link
Member

echarles commented Aug 31, 2023

Should we close this? If there are any other issue like theming... please open new dedicated issues. Thx!

@BrandonEscamilla
Copy link
Contributor Author

Hi @echarles, perhaps we should wait a little longer until the issue in (#94) is resolved. That way, I can test the widgets issue when there are changes in the path. Thank you in advance!

@echarles echarles added question Further information is requested discuss labels Dec 28, 2023
@echarles
Copy link
Member

@BrandonEscamilla In the meantime #94 is resolved. Could we close this?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
discuss question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants