[Notebook] Testing Bokeh Interactive Plot on Nikola Sites
This post shows how to add interactive data visualizations to Nikola-powered websites. Everything will be done in Jupyter notebooks! I use Bokeh as an example but similar approaches should work with other JavaScript-based tools like Plotly. For the impatient, drag to the end of this page to see the results.
For deploying website with Nikola, see my previous post.
!nikola --version
%matplotlib inline
import matplotlib.pyplot as plt
import numpy as np
Some boring stuff to test basic notebook display...¶
Non-executing code snippet:
print('Hello')
Other languages:
if (i=0; i<n; i++) {
printf("hello %d\n", i);
}
Latex: $$e^x=\sum_{i=0}^\infty \frac{1}{i!}x^i$$
Table:
This | is |
---|---|
a | table |
# test matplotlib rendering
plt.plot(np.sin(np.linspace(-5, 5)));
Static plots work fine but are a bit boring. Let's create some interactivity.
Interactive visualization with HvPlot and Bokeh¶
HvPlot provides high-level plotting API built on top of the well-known Bokeh library. Its API is very similar to pandas.DataFrame.plot()
, so you don't need to learn too many Bokeh/Holoview-specific syntaxes.
It can be installed easily by pip install hvplot
, with all major depedencies.
from IPython.display import HTML
import bokeh
from bokeh.resources import CDN, INLINE
from bokeh.embed import file_html
import holoviews as hv
import pandas as pd
import hvplot.pandas
bokeh.__version__, hv.__version__
Creating a demo plot¶
Taken from HvPlot tutorial.
# just some fake data
index = pd.date_range('1/1/2000', periods=1000)
np.random.seed(42)
df = pd.DataFrame(np.random.randn(1000, 4), index=index, columns=list('ABCD')).cumsum()
df.head()
plot = df.hvplot()
plot # The plot shows up in notebook, but not in Nikola-generated website.
By default the figure is not shown on the Nikola-generated website (i.e. the page you are looking at right now). A few more code is needed for displaying the figure.
Convert to HTML and display¶
We just need to convert the figure to raw HTML texts and use IPython.display.HTML()
to show it:
html_cdn = file_html(hv.render(plot), CDN) # explained later
HTML(html_cdn)
html_cdn
is simply a Python string containing HTML:
type(html_cdn)
It can be generated from a Bokeh figure by bokeh.embed.file_html()
. Simplying calling bokeh.embed.file_html(plot)
will lead to an error because our plot
object is not a bokeh figure yet:
type(plot)
You need to use hv.render()
to convert Holoview output to Bokeh figure.
type(hv.render(plot))
So the full command becomes HTML(file_html(hv.render(plot), CDN))
. The CDN
option says that part of the HTML/CSS/JS code will be retrived from a Content Delivery Network, not stored locally. You may also use INLINE
to store all code locally. This allows you to view the HTML file without internet connection but increases the file size:
html_inline = file_html(hv.render(plot), INLINE)
len(html_inline), len(html_cdn) # The inline one is 5x bigger
import geoviews as gv
gv.extension('bokeh')
gv.__version__
tile = gv.tile_sources.Wikipedia
tile # The background map. Can be zoomed-in to a great detail.
# Again you need a few more code to show the figure on web
HTML(file_html(hv.render(tile), CDN))
# Overlay some data points
from bokeh.sampledata.airport_routes import airports
airports_filtered = airports[(airports['City'] == 'New York') & (airports['TZ'] == 'America/New_York')]
airports_filtered
plot_geo = tile * airports_filtered.hvplot.points('Longitude', 'Latitude', geo=True,
color='red', size=150, width=750, height=500)
HTML(file_html(hv.render(plot_geo), CDN)) # airport locations around NYC
Comments
Comments powered by Disqus