I am trying out Holoviews for the first time, and I'd like to reproduce this animated "Gapminder" plot as described here.
The code runs but I do not know how to handle the output so that it is displayed in a Jupyter Notebook (I assume that is possible, since Jupyter can display arbitrary HTML).
# Get HoloViews plot and attach document
doc = curdoc()
hvplot = BokehRenderer.get_plot(hvgapminder, doc)
# Make a bokeh layout and add it as the Document root
plot = layout([[hvplot.state], [slider, button]], sizing_mode='fixed')
doc.add_root(plot)
Specifically, what should I do with the resulting doc
or hvplot
objects?
That particular example combines both HoloViews and bokeh components and bokeh widgets cannot easily communicate with Python in the notebook. You can however use the holoviews 'scrubber' widget to achieve the same thing:
import pandas as pd
import numpy as np
import holoviews as hv
from bokeh.sampledata import gapminder
hv.extension('bokeh')
# Switch to sending data 'live' and using the scrubber widget
%output widgets='live' holomap='scrubber'
# Declare dataset
panel = pd.Panel({'Fertility': gapminder.fertility,
'Population': gapminder.population,
'Life expectancy': gapminder.life_expectancy})
gapminder_df = panel.to_frame().reset_index().rename(columns={'minor': 'Year'})
gapminder_df = gapminder_df.merge(gapminder.regions.reset_index(), on='Country')
gapminder_df['Country'] = gapminder_df['Country'].astype('str')
gapminder_df['Group'] = gapminder_df['Group'].astype('str')
gapminder_df.Year = gapminder_df.Year.astype('f')
ds = hv.Dataset(gapminder_df)
# Apply dimension labels and ranges
kdims = ['Fertility', 'Life expectancy']
vdims = ['Country', 'Population', 'Group']
dimensions = {
'Fertility' : dict(label='Children per woman (total fertility)', range=(0, 10)),
'Life expectancy': dict(label='Life expectancy at birth (years)', range=(15, 100)),
'Population': ('population', 'Population')
}
# Create Points plotting fertility vs life expectancy indexed by Year
gapminder_ds = ds.redim(**dimensions).to(hv.Points, kdims, vdims, 'Year')
# Define annotations
text = gapminder_ds.clone({yr: hv.Text(1.2, 25, str(int(yr)), fontsize=30)
for yr in gapminder_ds.keys()})
# Define options
opts = {'plot': dict(width=1000, height=600,tools=['hover'], size_index='Population',
color_index='Group', size_fn=np.sqrt, title_format="{label}"),
'style': dict(cmap='Set1', size=0.3, line_color='black', alpha=0.6)}
text_opts = {'style': dict(text_font_size='52pt', text_color='lightgray')}
# Combine Points and Text
(gapminder_ds({'Points': opts}) * text({'Text': text_opts})).relabel('Gapminder Demo')