10

I created a notebook which should display plots in a tab widget. As far as I understand, to include something like plots in the tab widget, I need to wrap it in the output widget. In the notebook itself it works but when I convert it to html via nbconvert it produces the wrong output.

Widgets like sliders, buttons or text appear within the tab widget where they should, but when I use the output widget to catch the plot (or even some text from a print() function) it appears before the tab environment which itself is then empty.

This is the how it shoud look with one plot per tab (works in the notebook): Plots in tabs within notebook

And this is how it looks after nbconvert (in html). The plots appear before the tab envorinment: Plots before tabs in html

Please note that nbconvert includes other widgets fine and also tabs with other content.

This is the used code:

# Import libraries
import pandas as pd
import matplotlib.pyplot as plt
import ipywidgets as widgets
import numpy as np

# Generated data for plotting
data = pd.DataFrame()
for i in range(5):
    data[i] = np.random.normal(size = 50)

Now this part works in the notebook but not in the html, but as you will see it seems to be related to the output widget, as I does not work with plots or printed text.

# This does not work with plots
children = []
for i in range(data.shape[1]):
    out = widgets.Output()
    with out:
        fig, axes = plt.subplots()
        data[i].hist(ax = axes)
        plt.show()
    children.append(out)
tab = widgets.Tab()
tab.children = children
for i in range(len(children)):
    tab.set_title(i, "Plot " + str(i))
tab

# And this does not work with printed output
children = []
for i in range(5):
    out = widgets.Output()
    with out:
        print("This is text", i)
    children.append(out)
tab = widgets.Tab()
tab.children = children
for i in range(len(children)):
    tab.set_title(i, "Text " + str(i))
tab

However, if I use a different widget type (e.g. Text) it is displayed correctly in the notebook and the html output from nbconvert.

# This works with the Text widget
children = []
for i in range(5):
    out = widgets.Text(description="P"+str(i))
    children.append(out)
tab = widgets.Tab()
tab.children = children
for i in range(len(children)):
    tab.set_title(i, "Text " + str(i))
tab

So, is there something I can change to make this actually work? What I need in the end is a way to display N plots in N tabs...

Benedikt
  • 105
  • 7
  • Using an observe method solved it for me. https://stackoverflow.com/questions/56949504/how-to-lazify-output-in-tabbed-layout-in-jupyter-notebook – frostbite Nov 17 '19 at 15:38
  • I had the same problem. I tried using nbconvert with `--ExecutePreprocessor.store_widget_state=True` it does store the state but the output goes to the wrong cell. The only solution right now is to open Jupyter Notebook, and run it manually then go Widgets > Save Widget State. Then use nbconvert, that would show the output where it should be. I think the problem is that nbconvert doesnt have a JS engine (for obvious reasons) so its not possible to do what we want. – danielfrg Dec 20 '19 at 03:05
  • I reported an issue upstream [here](https://github.com/jupyter/nbconvert/issues/1199) – Eric Feb 24 '20 at 16:57

1 Answers1

1

I had the same problem. Updating nbconvert (for example via pip install --upgrade nbconvert) solved it.

Quoting from https://github.com/jupyter/nbconvert/issues/923 :

MSeal commented on 2020-09-07:

Yes, this issue was resolved in jupyter/nbclient#24 and nbclient >= 0.4.0 has the fix. NBconvert 6.0 (which should be releasing tomorrow) defaults to using nbclient and the issue overall should disappear. You can try it out on the 6.0.0rc0 release today if you like.

Kilian Batzner
  • 5,420
  • 2
  • 32
  • 44