How to stop bokeh from opening a new tab in Jupyter Notebook? - python

First of all, before this is tagged as duplicate, I have read the other solutions and unfortunately none of them worked for me.
My problem is that I want to display a bokeh plot in Juypter Notebook (and only in Jupyter Notebook), not in a new tab/window.
In the official documentation here I am told that I only need to change
output_file
to
output_notebook
Even though the plot is now displayed inline if I do that, bokeh won't stop also opening a new tab and needlessly displaying the plot there.
Since I'm gonna create lots of plots in my project, it'd be very nice to not always have to close this new tab and return to notebook, but just have it stop creating new tabs, just as it would work with e.g. matplotlib.
What confuses me is that if I load up the official tutorial and enter code there, for example
import numpy as np
x = np.linspace(0, 10, 100)
y = np.exp(x)
p = figure()
p.line(x, y)
show(p)
there is no new tab opened. If I now run the same code locally on my machine's Juypter Notebook, it does open up a new tab.
I've been trying for a while now to fix this, any help would be very much appreciated.
Thanks in advance, Vincent

You need to call output_notebook at the top of your notebook, but only call output_notebook. If you call output_file at all, that activates a persistent mode that saves output to files, and causes show to open new tabs with those files. You would need to call reset_output to clear that persistent mode.
As a convenience, since several users asked for it, if no output mode is supplied, show behaves as though output_file was called as a default. The reason a tab is not opened from the Binder tutorial is because it is not technically possible for code running remotely on Binder server to open a tab on your local browser (which is a very good thing).

Adding an explicit example to #bigreddot's answer:
You might have ran bokeh.io.output_file() somewhere in your notebook, to save noteable graphs. However, now you only want to experiment with some plots quickly to inspect the data.
Simply reset your settings to stop saving to file in any cell in your notebook like so:
import bokeh.io
# this is here only for completeness to clarify where
# the methods are nested (you probably already imported this earlier)
bokeh.io.reset_output()
bokeh.io.output_notebook()
You can activate saving to file again later to keep the interesting graphs.

You can import:
from bokeh.plotting import output_notebook
And call output_notebook before your figures declaration, then you just show the figure using show. See the doc.

Related

How to get ipywidgets interact to work in HTML?

I have a Jupyter notebook with the following cell:
from ipywidgets import widgets, interact
slider = widgets.IntSlider()
def print_val(v):
print(v)
interact(print_val,v=slider)
This works fine in the notebook - when I change the slider the printed output changes. But when I use nbconvert to convert the notebook into HTML, the slider still renders fine in the output HTML, but has no effect on the printed output.
Any idea how to get this to work? Maybe ipywidgets is not the right library for this kind of stuff?
Thanks!
I think you miss what nbconvert does. This utility is needed for converting notebooks to other formats, such as PDF, LATEX, etc. It is used for sharing and presentation. One loses the interactivity option once the notebook is converted.
The interactivity of the Jupyter notebook is provided by the Jupyter server that is started when you invoke jupyter notebook from command line.
So when you save notebook as a web page or convert it to HTML, you don't have the server back end part that processes all the changes. It is a static web page. Because the slider is a standard element it is rendered correctly, but nothing happens when you slide it: there is nothing "attached" to it to handle the events.
At the end, in order to be able to interact with Jupyter notebook, you need the some kind of Jupyter server to be running. It can be a local server if you need it only for yourself, or you can use Google Colab (or Jupyter Hub) if you want to collaborate with others.
Also, there are several solutions that allow one to have some interactivity on the graphs, like Bokeh and Plotly. They also require you to run some kind of server.
Of course, all that is relevant only if you need Python to process your data. If your needs are simple as showing the slider value you better off with a simple Javascript, that can handle the slider changes right in the browser, without the need to run any server at the back end.
An interesting option, although not a direct solution: voila.

How to save figures in a folder with Jupyter Notebook when the plots are produced with an external function that I don't want to modify?

I want to save figures plotted by a function that I don't want to have to touch (because it is an external function, and also because if tomorrow I don't want to save them and just display on the console, I don't want to have to edit the source code again and again). Is it possible to save the figures into a folder from ipython? Whether the figures are plotted in iPython or not is not a concern. I just want to be able to save them in a folder automatically, as they are a lot in number.
I have tried most of the solutions mentioned here, but they don't work - they just save a blank image file.
import matplotlib.pyplot as pl
fig = pl.figure()
external_function(parameters) # this function plots a figure
fig.savefig(r'path\to\folder\image.png') # saves a blank image.png into the folder
fig.savefig must be before show because when you close the figure, it is destroyed and only an empty (will appear blank) figure is saved.
There are several approaches, all of which require a modification of the external function that you don't want to change:
1 - modify the external function by adding a parameter to indicate if the figure must be saved or not, then using a conditional to save the figure or not.
def external function(params, dosave=False):
...
if dosave:
fig.savefig...
fig.show()
2 - modify the external function to return a figure that you can then choose to save prior to displaying it.
3 - Possibly decorate the external function so it saves the figure.
There may be a 'hacky way' to use ipython internals to keep a handle on the figures you are closing, but I don't know it.

Plotly + iPython Notebook - Plots Disappear on Reopen

When I create a notebook with plotly plots, save and reopen the notebook, the plots fail to render upon reopening - there are just blank blocks where the plots should be. Is this expected behavior? If not, is there a known fix?
Check to make sure your notebook is marked as "trusted", either in the top-right corner of the notebook, or in the File menu.
My notebooks are trusted by default, but I managed to reproduce your observed behaviour by temporarily removing my ~/Library/Jupyter/nbsignatures.db file, which forces Jupyter to run the notebook as untrusted. Clicking the tile in the top-right corner to trust the notebook fixed the issue for me.
This page in the jupyter docs, Security in notebook documents explains further:
The security problem we need to solve is that no code should execute just because a user has opened a notebook that they did not write. Like any other program, once a user decides to execute code in a notebook, it is considered trusted, and should be allowed to do anything.
I also meet this annoying issue. I find no way to reveal them on the notebook, but I find a compromise way to display them on an html page that is File -> Print Preview.
The reason as documented here:
Note: Default renderers persist for the duration of a single session,
but they do not persist across sessions. If you are working in an
IPython kernel, this means that default renderers will persist for the
life of the kernel, but they will not persist across kernel restarts.
As indicated in the troubleshooting documentation, "JupyterLab Problems" section, You have two options to solve the problem:
calling fig.show("notebook") instead of just fig.show().
If this problem is recurrent, you can use this:
import plotly.io as pio
pio.renderers.default='notebook'
Credits for here

What's wrong with Pandas plot?

I'm following a book by Wes McKinney and in the section introducing pandas, he's given a simple example of plotting a pandas Data Frame. Here're the lines I wrote:
tz_counts = frame['tz'].value_counts() # frame is a Data Frame
tz_counts[:10] # works fine till here. I can see the key-value I wanted
tz_counts[:10].plot(kind='barh', rot=0)
It just prints a line on screen that says
<matplotlib.axes.AxesSubplot object at 0x3d14ed0>
rather than displaying a plot window as I'd expect with matplotlib's plot function. What's wrong here? How can I make it work?
Matplotlib doesn't show the plot until you tell it to, unless you're in "interactive" mode.
Short Answer: Call plt.show() when you're ready to display the plot.
This starts the gui mainloop of whatever backend you're using, so it is blocking. (i.e. execution will stop until you close the window)
If you want it to show up automatically without stopping execution, you can turn on interactive mode either with plt.ion() or by using ipython --pylab.
However, using --pylab mode in ipython will import all of numpy, matplotlib.pyplot, and a few other things into the global namespace. This is convenient for interactive use, but teaches very bad habits and overwrites functions in the standard library (e.g. min, max, etc).
You can still use matplotlib's interactive mode in ipython without using "pylab" mode to avoid the global import. Just call plt.ion()
Matplotlib's default TkAgg backend will work in interactive mode with any python shell (not just ipython). However, other backends can't avoid blocking further execution without the gui mainloop being run in a separate thread. If you're using a different backend, then you'll need to tell ipython this with the --gui=<backend> option.
Try using:
%matplotlib
tz_counts = frame['tz'].value_counts()
tz_counts[:10].plot(kind='barh', rot=0)
Using % matplotlib prevents importing * from pylab and numpy which in turn prevents variable clobbering.

show() doesn't redraw anymore

I am working in linux and I don't know why using python and matplotlib commands draws me only once the chart I want.
The first time I call show() the plot is drawn, wihtout any problem, but not the second time and the following.
I close the window showing the chart between the two calls. Do you know why and hot to fix it?
Thanks AFG
from numpy import *
from pylab import *
data = array( [ 1,2,3,4,5] )
plot(data)
[<matplotlib.lines.Line2D object at 0x90c98ac>]
show() # this call shows me a plot
#..now I close the window...
data = array( [ 1,2,3,4,5,6] )
plot(data)
[<matplotlib.lines.Line2D object at 0x92dafec>]
show() # this one doesn't shows me anything
in windows this works perfect:
from pylab import *
plot([1,2,3,4])
[<matplotlib.lines.Line2D object at 0x03442C10>]
#close window here
plot([1,2,3,4])
[<matplotlib.lines.Line2D object at 0x035BC570>]
did you try with:
from matplotlib import interactive
interactive(True)
sometimes matplotlib produces some headaches because we have to remember that some options are set in matplotlibrc (such as the backend or the interactive parameters). If you use matplotlib from different editors (IDLE-tk, pycrust-wxpython) or alternating interactive with scripting, then you have to take into account that the configuration that works in one mode could give you problems in the other mode and must be modified programmatically or using a dedicated configuration file.
The example I give, works directly (and without show()) because in matplotlibrc I have interactive set to True as default
You likely have conflicts between your editor/IDE windowing system, and your plot windows.
A very good way around this is to use IPython. IPython is a great interactive environment, and has worked out these issues plus has many other advantages. At the beginning, start IPython with the command (from a terminal window) ipython -pylab to put it in the interactive pylab mode.
I'm guessing that you are doing this in IDLE on Windows because that's where I've noticed this same problem.
From what I've deduced, there is a problem with using the TkAgg backend,which comes with the basic Python dist and appears to be the default for matplotlib, when using matplotlib with IDLE. It has something to do with the way IDLE uses subprocesses because if I start IDLE with the -n option, which disables subprocesses, I don't have this problem. An easy way to start it IDLE with the -n option on Windows is to right click and file and select 'Open with IDLE'. If you do this you should get an IDLE shell which says
=== No Subprocess ===
just above the prompt. For instance, borrowing code from joaquin's solution, you could try this simple code:
from matplotlib import interactive
interactive(True)
from pylab import *
plot([1,2,3,4])
then close the window and type the last line into the console again. It works for me in IDLE with the -n option.
So what can you do? You can always run IDLE in the mode without subprocesses, but there are dangers to that. You can use a different IDE. Many people suggest IPython though I'm not sold on it yet myself. You could also try a different backend for matplotlib. I'm going to try that in a little while cause I've been wondering whether it will work.
show() is only meant to be used once in a program, at the very end: it is a never ending loop that checks for events in the graphic windows.
The normal way of doing what you want is:
# … plot …
draw() # Draws for real
raw_input() # Or anything that waits for user input
# … 2nd plot …
draw()
raw_input()
# Last plot
show() # or, again, draw(); raw_input()
You could try to see whether this works for you.
Alternatively, you can try to change the backend, as some backends work better than others:
import matplotlib
matplotlib.use('TkAgg') # For other backends, do matplotlib.use('') in a shell

Categories

Resources