jupyter-widgets / ipywidgets

Interactive Widgets for the Jupyter Notebook
https://ipywidgets.readthedocs.io
BSD 3-Clause "New" or "Revised" License
3.16k stars 950 forks source link

Output widget does not show matplotlib figure created before display #2169

Open codingS3b opened 6 years ago

codingS3b commented 6 years ago

When using the %matplotlib notebook command for getting nicer matplotlib plots, I experienced a strange behavior, but don't know if it is actually a bug or I am doing something stupid: When creating a figure in the context of an output widget before displaying the output widget, the figure gets lost somewhere and is not shown, even after the display command was issued. Even stranger, the print statement gets captured nonetheless and is displayed correctly.

When displaying the output widget first and only later creating the plot, everything is alright.

%matplotlib notebook

import numpy as np
import matplotlib.pyplot as plt
from ipywidgets import widgets
from IPython.display import display

out = widgets.Output(layout={'border': '1px solid black'})

# uncomment next line and comment display 
# command after plt.subplots(..) to get working version
#display(out)

with out:
    print("output widget capture!")
    fig, ax = plt.subplots(1,1)

# the fig will not be displayed, but the print will
display(out)

x = np.linspace(0, 10, 200)        
with out:
    ax.plot(x, x**2)
jasongrout commented 6 years ago

Some of the matplotlib renderers (at least the inline, and I think the notebook one) bypass the notebook output system to render plots. See https://github.com/jupyter-widgets/ipywidgets/issues/1853#issuecomment-349201240 for an explanation. Does that explanation help?

codingS3b commented 6 years ago

Thanks for pointing to that issue! I will try to fix my problem with the matplotlib notebook the same way as you suggested. Also I was not even aware of the matplotlib jupyter extension, this might be just what I need :)

codingS3b commented 6 years ago

Changing the matplotlib mode to inline and changing the code to

%matplotlib inline

out = widgets.Output(layout={'border': '1px solid black'})

# this works as expected
#display(out)

with out:
    print("output widget capture!")
    fig, ax = plt.subplots(1,1)
    #show_inline_matplotlib_plots()

# does not show the figure
display(out)

x = np.linspace(0, 10, 200)        
with out:
    ax.plot(x, x**2)
    show_inline_matplotlib_plots()

this now indeed works, but not with %matplotlib notebook. There the figure appears very briefly and then disappears. I guess I will have to check out the jupyter extension for matplotlib.

jasongrout commented 6 years ago

I don't think I've seen the notebook renderer work in jupyterlab - actually, I'm surprised the figure appears at all with that backend. It's pretty specific to the classic notebook, IIRC.

codingS3b commented 6 years ago

Well, I did not use jupyterlab, only jupyer notebook. Sorry if that caused any confusion.