This is a follow-up issue to #5754, in which we widgetized the Matplotlib nbagg backend for Jupyter notebooks.
I'm using this pretty extensively, so I'm happy to report issues I find here. I'd also like to personally fix them, but I will need some guidance on how to do that. So far, I've found 3 things that we should fix:
The Matplotlib widget does not respect layout widgets as much as it should.
If I place widgets in layouts, they are autoscaled to not run over the sides of the notebook (for instance). Matplotlib always defaults to a particular size, which means it often runs over. See the below screenshot
The titlebars seem unnecessary much of the time.
I suspect most users in notebooks don't really care about having a titlebar in the figure. We should make it easy to turn this off. Maybe this should be the default? Is it already possible to do so?
Getting the widget that needs to be added to Jupyter layouts is mysterious.
To actually put the widget in a layout, one needs to get fig.canvas.manager.canvas and add that to a layout. That's not really the API we want, is it? Is there a way we can make this easier?
Regarding 1 we are currently using the scroll event hack in bqplot to
detect resize events.
It should not be necessary anymore with phosphor layout. I think that we
could use the same trick with the matplotlib widget.
On May 12, 2016 7:20 PM, "Steven Silvester" notifications@github.com
wrote:
I'm pretty well saturated at this point, but can offer a few suggestions:
There must be a way that widgets in a ipywidgets layout are notified of
changes that could be hooked in to.
The figure title can be used to show that two figures are in fact
identical.
This is the canonical way of embedding a matplotlib figure into another
GUI (same way it is done in Qt).
—
You are receiving this because you were mentioned.
Reply to this email directly or view it on GitHub #6414 (comment)
@izaid sorry for the late reply. I spent most of my time in airports in the last 3 days...
The problem you have is that the browser does not provide resize events for DOM elements. (There is only a window.resize event). In the case of a CSS flexbox, there are multiple other reasons than a window resize that can cause things to relayout, and trying to catch them all is not realistic.
In the case of libraries like phosphor js, which is the one used for the new jupyterlab, all dom elements are sized and positioned absolutely and we know when things are resized. So in the bright future of JupyterLab, things will be better.
In the meantime (before JupyterLab is released and becomes the main notebook) there are ways to emulate DOM element resize events, such as the one we use in the bqplot PR bqplot/bqplot#131, which is not great in terms of performance but does the job.
I guess that this could be used for matplotlib too.
Regarding the matplotlib widget, I believe that the [notebook/web] backend and the widget wrapping should be in a different GitHub repo than the main matplotlib one.
We now have a cookiecutter repo for custom Jupyter widget library https://github.com/jupyter/widget-cookiecutter. The thing is that Jupyter is a fast moving target and you probably want the notebook integration to evolve independently from the matplotlib release cycle. Besides, it will make it easy to add the support for Jupyterlab when it is released.
I am nominally 👍 on pulling the notebook backend out of the mainline. Maybe pull the inline backend out of IPython as will and put both of them in a repo in the Jupyter/IPython part of the world?
I am a +0 on pulling the web backend out, it runs its own tornado server and has a independent js front end, but I think that some of the js is reused in the notebook widget so splitting them up make less sense so pulling them out together and putting them in a repo under the mpl organization makes sense (so long as there is still a way to have mpl re-import the web backend without picking up a hard jupyter dependency).
@tacaswell, I talked with Sylvain about this today. We could create a separate package under matplotlib that has the { web, inline, notebook } backends and would not depend on Jupyter unless using the inline or notebook backends.
@tacaswell besides, the thing is that as soon as Matplotlib follows the jupyter-js-widgets practices, embedding live matplotlib figures in any webpage with or without a backend will come for free.
Example here with the ipyleaflet widget:
I wonder if you will want to keep maintaining a matplotlib specific tornado based server...
Okay, some progress here. First, the trick @SylvainCorlay is indeed very good at getting resize events, so that's great.
The problem here, however, seems to be that the width and height passed to the resize event (including the existing ones) is not what I would expect. If I manually set the width of the widget in Jupyter, the width passed to the resize event is very different. It does change, just not in the ways I would expect...
Edit: And, to be clear, it's not a pixels vs inches thing. Everything seems to be clearly in pixels.
Activity
jenshnielsen commented on May 12, 2016
Other issues that I noticed while working on it.
The figure closing both from the Python side and from the widget is not respected as document in the UAT notebook
I.e.
Do something like
One cell
close the figure widget.
and execute something from a different cell:
And observe that no new figure is created.
Creating a figure attached to an ipywidte interact and exporting the figure followed by touching the slider widget leads to lot of blank white space.
blink1073 commented on May 12, 2016
I'm pretty well saturated at this point, but can offer a few suggestions:
SylvainCorlay commented on May 12, 2016
Regarding 1 we are currently using the scroll event hack in bqplot to
detect resize events.
It should not be necessary anymore with phosphor layout. I think that we
could use the same trick with the matplotlib widget.
On May 12, 2016 7:20 PM, "Steven Silvester" notifications@github.com
wrote:
izaid commented on May 12, 2016
Okay, so here is my attempt so far to solve 1). What I did was add observers to some traits in the Matplotlib widget's layout, e.g. https://github.com/ipython/ipywidgets/blob/master/ipywidgets/widgets/widget_layout.py#L31 -- this works for simple things, like changing the width and height, but not sure how we'd extend it to the whole flex layout.
@SylvainCorlay, are you saying I can get away with just a single event with some scroll event hack? Can you point me to where in bqplot you do this?
SylvainCorlay commented on May 15, 2016
@izaid sorry for the late reply. I spent most of my time in airports in the last 3 days...
The problem you have is that the browser does not provide resize events for DOM elements. (There is only a window.resize event). In the case of a CSS flexbox, there are multiple other reasons than a window resize that can cause things to relayout, and trying to catch them all is not realistic.
In the case of libraries like phosphor js, which is the one used for the new jupyterlab, all dom elements are sized and positioned absolutely and we know when things are resized. So in the bright future of JupyterLab, things will be better.
In the meantime (before JupyterLab is released and becomes the main notebook) there are ways to emulate DOM element resize events, such as the one we use in the bqplot PR bqplot/bqplot#131, which is not great in terms of performance but does the job.
I guess that this could be used for matplotlib too.
SylvainCorlay commented on May 15, 2016
Regarding the matplotlib widget, I believe that the [notebook/web] backend and the widget wrapping should be in a different GitHub repo than the main matplotlib one.
We now have a cookiecutter repo for custom Jupyter widget library https://github.com/jupyter/widget-cookiecutter. The thing is that Jupyter is a fast moving target and you probably want the notebook integration to evolve independently from the matplotlib release cycle. Besides, it will make it easy to add the support for Jupyterlab when it is released.
cc @blink1073 @jasongrout
tacaswell commented on May 16, 2016
I am nominally 👍 on pulling the notebook backend out of the mainline. Maybe pull the inline backend out of IPython as will and put both of them in a repo in the Jupyter/IPython part of the world?
I am a +0 on pulling the web backend out, it runs its own tornado server and has a independent js front end, but I think that some of the js is reused in the notebook widget so splitting them up make less sense so pulling them out together and putting them in a repo under the mpl organization makes sense (so long as there is still a way to have mpl re-import the web backend without picking up a hard jupyter dependency).
blink1073 commented on May 16, 2016
@tacaswell, I talked with Sylvain about this today. We could create a separate package under matplotlib that has the { web, inline, notebook } backends and would not depend on Jupyter unless using the inline or notebook backends.
izaid commented on May 16, 2016
I'm +1 to this as well. What @SylvainCorlay didn't mention is that he's already done it -- https://github.com/sylvaincorlay/jupyter-matplotlib ;)
I've got this working now, maybe it makes more sense to work off of that?
SylvainCorlay commented on May 16, 2016
@tacaswell besides, the thing is that as soon as Matplotlib follows the jupyter-js-widgets practices, embedding live matplotlib figures in any webpage with or without a backend will come for free.
Example here with the ipyleaflet widget:
I wonder if you will want to keep maintaining a matplotlib specific tornado based server...
tacaswell commented on May 16, 2016
Fair enough
@SylvainCorlay I will give you enough permissions to move that repo into the mpl namespace.
izaid commented on May 16, 2016
Okay, some progress here. First, the trick @SylvainCorlay is indeed very good at getting resize events, so that's great.
The problem here, however, seems to be that the width and height passed to the resize event (including the existing ones) is not what I would expect. If I manually set the width of the widget in Jupyter, the width passed to the resize event is very different. It does change, just not in the ways I would expect...
Edit: And, to be clear, it's not a pixels vs inches thing. Everything seems to be clearly in pixels.
stonebig commented on Sep 30, 2017
any news ?
tacaswell commented on Oct 1, 2017
https://github.com/matplotlib/jupyter-matplotlib exists, it works for the notebook and integration with jupyter lab is on-going.
jklymak commented on Jan 17, 2021
I'm going to close this as thoroughly subsumed by ipympl. But feel free to re-open if I've misunderstood.