bqplot

Links: notebook, html, python, slides, GitHub

This library is well integrated with Jupyter and will probably stick for a long time. It mixes Python and Javascript. One drawback: you need to run the notebook everytime to get the graph, they don’t stay because Jupyter server is sending them, they don’t appear in the output.

source installation tutorial gallerie

%matplotlib inline
from jyquickhelper import add_notebook_menu
add_notebook_menu()

Setup

Le module est installé d’abord avec l’instruction pip install bqplot puis avec l’instruction jupyter nbextension enable --py bqplot. Sans cela, le notebook semble bloqué dans l’exécution du code utilisant ce module.

import bqplot

Premiers exemples de la documentation

from bqplot import pyplot as plt
import numpy as np
plt.figure(1)
np.random.seed(0)
n = 200
x = np.linspace(0.0, 10.0, n)
y = np.cumsum(np.random.randn(n))
plt.plot(x,y, axes_options={'y': {'grid_lines': 'dashed'}})
plt.show()
import numpy as np
from IPython.display import display
import bqplot as bq

size = 20
np.random.seed(0)

x_data = np.arange(size)

x_ord = bq.OrdinalScale()
y_sc = bq.LinearScale()

bar = bq.Bars(x=x_data, y=np.random.randn(2, size), scales={'x': x_ord, 'y': y_sc},
              type='stacked')
line = bq.Lines(x=x_data, y=np.random.randn(size), scales={'x': x_ord, 'y': y_sc},
                stroke_width=3, colors=['red'], display_legend=True, labels=['Line chart'])

ax_x = bq.Axis(scale=x_ord)
ax_y = bq.Axis(scale=y_sc, orientation='vertical', tick_format='0.2f', grid_lines='solid')

fig = bq.Figure(marks=[bar, line], axes=[ax_x, ax_y])
display(fig)

Animation

La seconde cellule définit le graphe. La troisième met à jour le graphique avec une nouvelle série. La mise à jour est progressive.

import numpy as np
import bqplot as bq
from IPython.display import display
xs = bq.LinearScale()
ys = bq.LinearScale()
x = np.arange(100)
y = np.cumsum(np.random.randn(2, 100), axis=1) #two random walks

line = bq.Lines(x=x, y=y, scales={'x': xs, 'y': ys}, colors=['red', 'green'])
xax = bq.Axis(scale=xs, label='x', grid_lines='solid')
yax = bq.Axis(scale=ys, orientation='vertical', tick_format='0.2f', label='y', grid_lines='solid')

fig = bq.Figure(marks=[line], axes=[xax, yax], animation_duration=1000)
display(fig)
#update data of the line mark
line.y = np.cumsum(np.random.randn(2, 100), axis=1)

Cartes

from IPython.display import display
from bqplot import (Figure, Map, Mercator, Orthographic, ColorScale, ColorAxis,
                    AlbersUSA, topo_load, Tooltip)
from pyquickhelper.filehelper import get_url_content_timeout
url = "https://raw.githubusercontent.com/bloomberg/bqplot/master/bqplot/map_data/"
sc_geo = Mercator()
x = Map(scales={'projection': sc_geo})
fig = Figure(marks=[x], title='Basic Map Example')
display(fig)
sc_geo = Mercator()
sc_c1 = ColorScale(scheme='YlOrRd')

map_styles = {'color': {643: 105., 4: 21., 398: 23., 156: 42., 124:78., 76: 98.},
              'scales': {'projection': sc_geo, 'color': sc_c1}}

axis = ColorAxis(scale=sc_c1)

if False:
    try:
        x = Map(map_data=topo_load('map_data/WorldMap.json'), **map_styles)
    except Exception as e:
        print(e)
        import os
        maps = os.path.abspath('WorldMap.json')
        get_url_content_timeout(url + 'WorldMap.json', output=maps)
        tl = topo_load(os.path.abspath("WorldMap.json"))
        x = Map(map_data=tl, **map_styles)

fig = Figure(marks=[x], axes=[axis],title='Choropleth Example')
display(fig)

On peut sélectionner des zones de la carte suivante. Je recommande l’usage de Firefox ou Chrome.

def_tt = Tooltip(fields=['id', 'name'])
map_mark = Map(scales={'projection': Mercator()}, tooltip=def_tt)
map_mark.interactions = {'click': 'select', 'hover': 'tooltip'}
fig = Figure(marks=[map_mark], title='Interactions Example')
display(fig)

Interactions

from bqplot import *
from IPython.display import display
import numpy as np
import pandas as pd
from ipywidgets import *
x_sc = LinearScale()
y_sc = LinearScale()

x_data = np.arange(20)
y_data = np.random.randn(20)

dd = Dropdown(options=['First', 'Second', 'Third', 'Fourth'])
scatter_chart = Scatter(x=x_data, y=y_data, scales= {'x': x_sc, 'y': y_sc}, default_colors=['dodgerblue'],
                       names=np.arange(100, 200), names_unique=False, display_names=False, display_legend=True,
                       labels=['Blue'])
ins = Button(icon='fa-legal')
scatter_chart.tooltip = ins

scatter_chart2 = Scatter(x=x_data, y=np.random.randn(20),
                         scales= {'x': x_sc, 'y': y_sc}, default_colors=['orangered'],
                         tooltip=dd, names=np.arange(100, 200), names_unique=False, display_names=False,
                         display_legend=True, labels=['Red'])

ax_x = Axis(scale=x_sc)
ax_y = Axis(scale=y_sc, orientation='vertical', tick_format='0.2f')

fig = Figure(marks=[scatter_chart, scatter_chart2], axes=[ax_x, ax_y])
display(fig)

La cellule suivante attrape les événements générées par la souris et affiche ce qu’elle attrape.

def print_event(self, target):
    print(target)

# Adding call back to scatter events
# print custom mssg on hover and background click of Blue Scatter
scatter_chart.on_hover(print_event)
scatter_chart.on_background_click(print_event)

# print custom mssg on click of an element or legend of Red Scatter
scatter_chart2.on_element_click(print_event)
scatter_chart2.on_legend_click(print_event)

On attrape un événement pour afficher un graphe plus complexe.

# Adding figure as tooltip
x_sc = LinearScale()
y_sc = LinearScale()

x_data = np.arange(10)
y_data = np.random.randn(10)

lc = Lines(x=x_data, y=y_data, scales={'x': x_sc, 'y':y_sc})
ax_x = Axis(scale=x_sc)
ax_y = Axis(scale=y_sc, orientation='vertical', tick_format='0.2f')
tooltip_fig = Figure(marks=[lc], axes=[ax_x, ax_y], min_height=400, min_width=400)

scatter_chart.tooltip = tooltip_fig
# Changing interaction from hover to click for tooltip
scatter_chart.interactions = {'click': 'tooltip'}