AutocompleteInput does not complete word when option is clicked - bokeh

I'm working in Jupyter notebook 5.7.4 bokeh 1.0.4, Firefox 63.0.3 python3.7, I want to get autocompletion using bokeh to get some interactive visualization.
from bokeh.models.widgets import AutocompleteInput
from IPython.display import HTML
input_widget = AutocompleteInput(completions=cList1, title='FTTH Keys', value='value')
l = layout([[input_widget],], sizing_mode='fixed')
curdoc().add_root(l)
curdoc().title = 'UI Test'
show(l)
when I write characters all is fine, but when I want to choose one element from the autocomplete list the word didn't complete in the input box.

Related

tqdm in Jupyter notebook does not show up

I would like to implement a progress bar in Jupyter notebook. I tried using tqdm as shown in the code below, but I just get this shown on the screen and the progress bar is...well...not progressing:
CODE
# Iterate through each sound file and extract the features
from tqdm import tqdm
items = len(metadata.index)
for i in tqdm(range(items), "Completed"):
for index, row in metadata.iterrows():
file_name = os.path.join(os.path.abspath(fulldatasetpath),'fold'+str(row["fold"])+'/',str(row["slice_file_name"]))
class_label = row["class_name"]
data = extract_features(file_name)
features.append([data, class_label])
Can you help me get the progress bar to progress? Thanks!
For Jupyter notebooks you should use a special version of tqdm:
from tqdm.notebook import tqdm

Using bokeh server in jupyter notebook behind proxy / jupyterhub

I want to develop bokeh apps on a jupyter notebook instance that runs behind jupyterhub (AKA an authenticating proxy). I would like to have interactive bokeh apps calling back to the notebook kernel. I don't want to use the notebook widgets etc because I want to be able to export the notebook as a python file and have something I can serve with bokeh server.
The following code in my notebook gives an empty output with no errors:
from bokeh.layouts import row
from bokeh.models.widgets import Button
from bokeh.io import show, output_notebook
from bokeh.application.handlers import FunctionHandler
from bokeh.application import Application
output_notebook()
# Create the Document Application
def modify_doc(doc):
layout = row(Button(label="Hello,"),Button(label="world!"))
doc.add_root(layout)
handler = FunctionHandler(modify_doc)
app = Application(handler)
# Output = BokehJS 0.12.10 successfully loaded.
# New cell
show(app, notebook_url="my-jupyterhub-url.com:80")
# Output = "empty" cell
Inspecting the cell a script tag has been added:
<script src="http://my-jupyterhub-url.com:46249/autoload.js?bokeh-autoload-element=f8fa3bd0-9caf-473d-87a5-6c7b9680648b&bokeh-absolute-url=http://my-jupyterhub-url.com:46249" id="f8fa3bd0-9caf-473d-87a5-6c7b9680648b" data-bokeh-model-id="" data-bokeh-doc-id=""></script>
This will not work because port 46249 isn't open on the jupyterhub proxy. Also the path that routes to my jupyter instance is my-jupyterhub-url.com/user/my-username/ so my-jupyterhub-url.com/autoload.js wouldn't route anywhere.
This feels like it could be a common requirement but a search hasn't revealed a solution to be yet.
Any ideas?
So I've found a solution that I'm not happy about but works.. just about.
First install nbserverproxy on your Jupyter instance. This allows you to proxy through JupyterHub (where you are authenticated) onto arbitrary ports on your Jupyter machine/container. I installed by opening a terminal from the Jupyter web front end and typing:
pip install git+https://github.com/jupyterhub/nbserverproxy --user
jupyter serverextension enable --py nbserverproxy --user
Then restart your server. For my install of JupyterHub this was control panel -> stop my server wait then start my server.
Finally I monkey patched the Ipython.display.publish_display_data (since the source code revealed that bokeh used this when calling show) in the notebook like so.
from unittest.mock import patch
from IPython.display import publish_display_data
orig = publish_display_data
import re
def proxy_replacer(display_data):
for key, item in display_data.items():
if isinstance(item, str):
item= re.sub(r'(/user/tam203)/?:([0-9]+)', r'\1/proxy/\2', item)
item = re.sub(r'http:' , 'https:', item)
display_data[key] = item
return display_data
def mock(data, metadata=None, source=None):
data = proxy_replacer(data) if data else data
metadata = proxy_replacer(metadata) if metadata else metadata
return orig(data, metadata=metadata, source=source)
patcher = patch('IPython.display.publish_display_data', new=mock)
patcher.start()
With that all done I was then able to run the following an see a nice dynamically updating plot.
import random
from bokeh.io import output_notebook
output_notebook()
from bokeh.io import show
from bokeh.server.server import Server
from bokeh.application import Application
from bokeh.application.handlers.function import FunctionHandler
from bokeh.plotting import figure, ColumnDataSource
def make_document(doc):
source = ColumnDataSource({'x': [], 'y': [], 'color': []})
def update():
new = {'x': [random.random()],
'y': [random.random()],
'color': [random.choice(['red', 'blue', 'green'])]}
source.stream(new)
doc.add_periodic_callback(update, 100)
fig = figure(title='Streaming Circle Plot!', sizing_mode='scale_width',
x_range=[0, 1], y_range=[0, 1])
fig.circle(source=source, x='x', y='y', color='color', size=10)
doc.title = "Now with live updating!"
doc.add_root(fig)
app = Application(FunctionHandler(make_document))
show(app, notebook_url="<my-domain>.co.uk/user/tam203/")
So while I'm happy to have found a work around it doesn't really feel like a solution. I think a smallish change in bokeh could solve this (something like a url template string where you can specify the path and the port).
According to the official bokeh documentation show(obj, notebook_url=remote_jupyter_proxy_url) accepts a notebook_url argument value. Apparently this can be a function that accepts a port argument value.
The documentation goes further by providing a reference implementation for the function remote_jupyter_proxy_url in the context of jupyterhub/jupyterlab and proxy extension.

how to make the plot, but not open a new tab in bokeh?

Here is what I do to make plots with bokeh
p1=make_plot(df)
output_file("out.html", title="out example")
show(p1)
This always open a new tab to refresh the plot, but I do not want that. It's enough to just refresh a tab with previous version of the plot.
How can I stop show() to open a new tab and just make the new plot?
I have tried the option broweser=None or broweser='' but that does not work.
Use save instead of show in the last step. This will save the plot instead of opening it in browser.
from bokeh.io import save
p1=make_plot(df)
output_file("out.html", title="out example")
save(p1)
You are looking for save(), not show()
from bokeh.io import output_file,show,save
from bokeh.plotting import figure
output_file('out.html',title='out example')
fig = figure()
show(fig) # will pop up in the browser
a = raw_input() # just press any key to continue
fig.line(range(10),range(10))
save(fig) # you can refresh your browser tab to see the change

jupyter declarativewidgets change style

In my jupyter notebook, I want to have an interactive table, that when the user selects a row, I show relevant values in another table or graph.
What I am currently trying to use is declarativewidgets (although if an easier alternative was presented, I would be just as glad)
I had no problem setting up an example worked fine, and it was trivial to link the event from one item to the next, but I have been unable to change the styling of the elements. In particular, I want to be able to control the background color (and even make it alternate by row) on a table by table basis. I mean, I will have several tables (the first linked to the next, linked to the next, etc.), and I want each table to have a different background color.
What I have so far:
from IPython.display import display, Image
from IPython.core.display import HTML
from ipywidgets import *
import declarativewidgets
import pandas as pd
declarativewidgets.init()
Then I import the urth-viz-table:
%%html
<link rel="import" href="urth_components/urth-viz-table/urth-viz-table.html"
is='urth-core-import'>
Then I have a function
def create_df():
return pd.DataFrame({'one' : pd.Series([1., 2., 3.], index=['a', 'b', 'c']),
'two' : pd.Series([1., 2., 3., 4.], index=['a', 'b', 'c', 'd'])})
And the next cell creates the first table:
%%html
<template is="urth-core-bind">
<urth-core-function ref="create_df"
result="{{create_df}}"
limit="1600"
delay="100"
auto>
</urth-core-function>
<urth-viz-table datarows="{{ create_df.data }}"
rows-visible="19"
selection="{{first_selection}}"
columns="{{ create_df.columns }}"
selection-as-object>
</urth-viz-table>
</template>
This works fine, and I am able to create new tables and graphs and link them to the behaviour of the previous table. What I have not been able to do is change any of the styling of the table, an specific example would be greatly appreciated.
I am using
python 3.6
jupyter 4.2.1
jupyter-dashboards 0.6.1
jupyter-declarativewidgets 0.7.0

Animated graphs in ipython notebook

Is there a way of creating animated graphs. For example showing the same graph, with different parameters.
For example is SAGE notebook, one can write:
a = animate([circle((i,i), 1-1/(i+1), hue=i/10) for i in srange(0,2,0.2)],
xmin=0,ymin=0,xmax=2,ymax=2,figsize=[2,2])
a.show()
This has horrible flickering, but at least this creates a plot that animates for me. It is based on Aron's, but Aron's does not work as-is.
import time, sys
from IPython.core.display import clear_output
f, ax = plt.subplots()
n = 30
x = array([i/10.0 for i in range(n)])
y = array([sin(i) for i in x])
for i in range(5,n):
ax.plot(x[:i],y[:i])
time.sleep(0.1)
clear_output()
display(f)
ax.cla() # turn this off if you'd like to "build up" plots
plt.close()
Update: January 2014
Jake Vanderplas has created a Javascript-based package for matplotlib animations available here. Using it is as simple as:
# https://github.com/jakevdp/JSAnimation
from JSAnimation import examples
examples.basic_animation()
See his blog post for a more complete description and examples.
Historical answer (see goger for a correction)
Yes, the Javascript update does not correctly hold the image frame yet, so there is flicker, but you can do something quite simple using this technique:
import time, sys
from IPython.display import clear_output
f, ax = plt.subplots()
for i in range(10):
y = i/10*sin(x)
ax.plot(x,y)
time.sleep(0.5)
clear_output()
display(f)
ax.cla() # turn this off if you'd like to "build up" plots
plt.close()
IPython widgets let you manipulate Python objects in the kernel with GUI objects in the Notebook. You might also like Sage hosted IPython Notebooks. One problem you might have with sharing widgets or interactivity in Notebooks is that if someone else doesn't have IPython, they can't run your work. To solve that, you can use Domino to share Notebooks with widgets that others can run.
Below are three examples of widgets you can build in a Notebook using pandas to filter data, fractals, and a slider for a 3D plot. Learn more and see the code and Notebooks here.
If you want to live-stream data or set up a simulation to run as a loop, you can also stream data into plots in a Notebook. Disclaimer: I work for Plotly.
If you use IPython notebook, v2.0 and above support interactive widgets. You can find a good example notebook here (n.b. you need to download and run from your own machine to see the sliders).
It essentially boils down to importing interact, and then passing it a function, along with ranges for the paramters. e.g., from the second link:
In [8]:
def pltsin(f, a):
plot(x,a*sin(2*pi*x*f))
ylim(-10,10)
In [9]:
interact(pltsin, f=(1,10,0.1), a=(1,10,1));
This will produce a plot with two sliders, for f and a.
If you want 3D scatter plot animations, the Ipyvolume Jupyter widget is very impressive.
http://ipyvolume.readthedocs.io/en/latest/animation.html#
bqplot is a really good option to do this now. its built specifically for animation through python in the notebook
https://github.com/bloomberg/bqplot
On #goger's comment of 'horrible flickering', I found that calling clear_output(wait=True) solved my problem. The flag tells clear_output to wait to render till it has something new to render.
matplotlib has an animation module to do just that. However, examples provided on the site will not run as is in a notebook; you need to make a few tweaks to make it work.
Here is the example of the page below modified to work in a notebook (modifications in bold).
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
from matplotlib import rc
from IPython.display import HTML
fig, ax = plt.subplots()
xdata, ydata = [], []
ln, = plt.plot([], [], 'ro', animated=True)
def init():
ax.set_xlim(0, 2*np.pi)
ax.set_ylim(-1, 1)
return ln,
def update(frame):
xdata.append(frame)
ydata.append(np.sin(frame))
ln.set_data(xdata, ydata)
return ln,
ani = FuncAnimation(fig, update, frames=np.linspace(0, 2*np.pi, 128),
init_func=init, blit=True)
rc('animation', html='html5')
ani
# plt.show() # not needed anymore
Note that the animation in the notebook is made via a movie and that you need to have ffmpeg installed and matplotlib configured to use it.

Resources