Custom hot keys/commands in jupyter - jupyter-notebook

Is there a way to create custom hotkeys/commands in jupiter?
For example, lets say I press Ctrl+1 and jupiter automatically pastes this code:
import pandas as pd
import util as x
asdasd
adsasd
asasdasd

Related

Seaborn code Anscombe’s quartet does not work

The Seaborn code does not work.
I use jupyterlite to execute seaborn python code. first, i import seaborn in the following way --
import piplite
await piplite.install('seaborn')
import matplotlib.pyplot as plt
import seaborn as sn
%matplotlib inline
But when I insert seaborn code like the following one then it shows many errors that i do not understand yet --
link of the code
the problem that I face
But I insert this code in the google colab it works nicely
google colab
The issue is getting the example dataset as I point out in my comments.
The problem step is associated with:
# Load the example dataset for Anscombe's quartet
df = sns.load_dataset("anscombe")
You need to replace the line df = sns.load_dataset("anscombe") with the following:
url = 'https://raw.githubusercontent.com/mwaskom/seaborn-data/master/anscombe.csv' # based on [Data repository for seaborn examples](https://github.com/mwaskom/seaborn-data)
from pyodide.http import open_url
import pandas
df = pandas.read_csv(open_url(url))
That's based on use of open_url() from pyodide.http, see here for more examples.
Alternative with pyfetch and assigning the string obtained
If you've seen pyfetch around, this also works as a replacement of the sns.load_dataset() line based on John Hanley's post, that uses pyfetch to get the CSV data. The code is commented further:
# GET text at URL via pyfetch based on John Hanley's https://www.jhanley.com/blog/pyscript-loading-python-code-in-the-browser/
url = 'https://raw.githubusercontent.com/mwaskom/seaborn-data/master/anscombe.csv' # based on [Data repository for seaborn examples](https://github.com/mwaskom/seaborn-data)
from pyodide.http import pyfetch
response = await pyfetch(url)
content = (await response.bytes()).decode('utf-8')
# READ in string to dataframe based on [farmOS + JupyterLite: Import a CSV of Animals](https://gist.github.com/symbioquine/7641a2ab258726347ec937e8ea02a167)
import io
import pandas
df = pandas.read_csv(io.StringIO(content))

floris.tools.power_rose.load() requires class instantiation

I am writing a script to load a PowerRose object from a file I pickled previously using floris.tools.power_rose.PowerRose.save(). The script looks like this:
# General modules
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
# FLORIS-specific modules
import floris.tools as wfct
import floris.tools.power_rose as pr
power_rose = pr.PowerRose(name, df_power, df_turbine_power_no_wake, df_turbine_power_baseline)
power_rose.load(filename = "PowerRose_All.p")
However, as is clear from the last two lines I have to instantiate the PowerRose class in order to load a PowerRose instance from a pickled PowerRose, which seems to me to be a causality problem. The only solution I can think of would be to create a DataFrames of the same size as "PowerRose_All.p" filled with zeros to use in the instatiation.
Yes, you need to instantiate a power_rose object before you can use the load method. However, you do not need to supply DataFrames to do this. This could be accomplished by:
import floris.tools.power_rose as pr
power_rose = pr.PowerRose()
power_rose.load(filename="PowerRose_All.p")

update chart with ipywidgets:

I'm using seaborn on jupyter notebook and would like a slider to update a chart. My code is as follows:
from ipywidgets import interact, interactive, fixed, interact_manual
import numpy as np
import seaborn as sns
from IPython.display import clear_output
def f(var):
print(var)
clear_output(wait=True)
sns.distplot(list(np.random.normal(1,var,1000)))
interact(f, var=10);
Problem: every time I move the slider, the graph is duplicated. How do I update the chart instead?
Seaborn plots should be handled as regular matplotlib plot. So you need to use plt.show() to display it as explained in this answer for example.
Combined with %matplotlib inline magic command, this works fine for me:
%matplotlib inline
from ipywidgets import interact
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
def f(var):
sns.distplot(np.random.normal(1, var, 1000))
plt.show()
interact(f, var = (1,10))
Another solution would be to update the data of the plot instead of redrawing a new one, as explained here: https://stackoverflow.com/a/4098938/2699660

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.

jupyter-notebook output for loop not showing

When i run my Jupyter-notebook with python2.7 and try to print items (of a list) using a for-loop it just won't output the print statement after importing the following packages:
import sys
import os
from hachoir_core.cmd_line import unicodeFilename
from hachoir_metadata import extractMetadata
from hachoir_parser import createParser
from hachoir_core.i18n import getTerminalCharset
from hachoir_core.tools import makePrintable
import pandas as pd
example code:
items = [1, 3, 0, 4, 1]
for item in items:
print (item)
output is blank.
When I use the exact same code before importing, it does show.
Looks like hachoir imports are the problem, whenever I import anything containing it, the output stops showing.
Reposting as an answer: The hachoir_metadata module appears to do something odd with stdout which breaks IPython: Bug report.
As described in that link, you need to add the following code before importing hachoir_metadata:
from hachoir_core import config
config.unicode_stdout = False

Resources