Tests Jupyter Notebook Ipywidgets & Appmode

Import

In [1]:
from __future__ import print_function
import ipywidgets as widgets
from ipywidgets import HBox, VBox, interact, fixed, interactive, interact_manual
import numpy as np
from numpy.random import rand
import matplotlib.pyplot as plt
from IPython.display import display
from bqplot import pyplot as bqplt
#%matplotlib inline

Test-1

In [2]:
@widgets.interact_manual(
    color=['blue', 'red', 'green'], lw=(1., 10.))
def plot(freq=1., color='blue', lw=2, grid=True):
    t = np.linspace(-1., +1., 1000)
    fig, ax = plt.subplots(1, 1, figsize=(8, 6))
    ax.plot(t, np.sin(2 * np.pi * freq * t),
            lw=lw, color=color)
    ax.grid(grid)

Test-2

In [3]:
freq_slider = widgets.FloatSlider(
    value=2.,
    min=1.,
    max=10.0,
    step=0.1,
    description='Frequency:',
    readout_format='.1f',
)
freq_slider
In [4]:
range_slider = widgets.FloatRangeSlider(
    value=[-1., +1.],
    min=-5., max=+5., step=0.1,
    description='xlim:',
    readout_format='.1f',
)
range_slider
In [5]:
grid_button = widgets.ToggleButton(
    value=False,
    description='Grid',
    icon='check'
)
grid_button
In [6]:
color_buttons = widgets.ToggleButtons(
    options=['blue', 'red', 'green'],
    description='Color:',
)
color_buttons
In [7]:
title_textbox = widgets.Text(
    value='Hello World',
    description='Title:',
)
title_textbox
In [8]:
color_picker = widgets.ColorPicker(
    concise=True,
    description='Background color:',
    value='#efefef',
)
color_picker
In [9]:
def plot2(b=None):
    xlim = range_slider.value
    freq = freq_slider.value
    grid = grid_button.value
    color = color_buttons.value
    title = title_textbox.value
    bgcolor = color_picker.value

    t = np.linspace(xlim[0], xlim[1], 1000)
    f, ax = plt.subplots(1, 1, figsize=(8, 6))
    ax.plot(t, np.sin(2 * np.pi * freq * t),
            color=color)
    ax.grid(grid)
In [10]:
button = widgets.Button(
    description='Plot',
)
button
In [11]:
@button.on_click
def plot_on_click(b):
    plot2()
In [12]:
tab1 = VBox(children=[freq_slider,
                      range_slider,
                      ])
tab2 = VBox(children=[color_buttons,
                      HBox(children=[title_textbox,
                                     color_picker,
                                     grid_button]),
                                     ])
In [13]:
tab = widgets.Tab(children=[tab1, tab2])
tab.set_title(0, 'plot')
tab.set_title(1, 'styling')
VBox(children=[tab, button])

Test-3

In [14]:
# génère des abscisses
x = np.arange(0,10,0.1)

# crée une figure y = f(x)
ma_figure = bqplt.figure(animation_duration = 300)
mon_tracé = bqplt.scatter(x, x**2, enable_move=True)
bqplt.xlabel('Axe des x')

# initialise une zone d’affichage de texte
resultat2 = widgets.Output()

# choix de la fonction à tracer -> crée automatiquement un menu déroulant
# modifie le tracé en fonction de la valeur du widget
# il est possible d’utiliser interact via un décorateur
# il est possible de fixer les variables ne devant pas faire l’objet d’un widget
@interact(fonction=['parabole', 'sinus', 'hasard'], x=fixed(x))
def choix_fonction(fonction, x):
    if fonction=='parabole':
        with mon_tracé.hold_sync():
            mon_tracé.x = x
            mon_tracé.y = x**2
            bqplt.ylabel('x au carré')
    if fonction=='sinus':
        with mon_tracé.hold_sync():
            mon_tracé.x = x
            mon_tracé.y = np.sin(x)
            bqplt.ylabel('sin(x)')
    if fonction=='hasard':
        with mon_tracé.hold_sync():
            mon_tracé.x = x
            mon_tracé.y = rand(len(x))
            bqplt.ylabel('Nombres aléatoires')

# fonction qui lit et affiche les coordonnées d’un point déplacé
def affiche(name, value):
    with resultat2:
        resultat2.clear_output()
        print('Le point n° %i a été déplacé en x = %f y = %f'
              %(value['index'], value['point']['x'],value['point']['y']))

# détecte le déplacement d’un point
mon_tracé.on_drag_end(affiche)     

# crée la GUI
# il est possible de mixer des widgets créés via interact avec d’autre définis « à la main »
widgets.VBox([ma_figure,resultat2])

Test-4

In [15]:
a = widgets.IntSlider()
b = widgets.IntSlider()
c = widgets.IntSlider()
ui = widgets.HBox([a, b, c])
def f(a, b, c):
    print((a, b, c))

out = widgets.interactive_output(f, {'a': a, 'b': b, 'c': c})

display(ui, out)

Test-5

Weather map

In [16]:
from ipyleaflet import Map, basemaps, basemap_to_tiles, Heatmap, TileLayer
from ipywidgets import AppLayout
from ipywidgets import HTML, Layout, Dropdown, Output, Textarea, VBox, Label
import bqplot as bq
import numpy as np
from pandas import date_range
In [17]:
OWM_API_KEY = "7dac0f28a9d7f242413d749b3c3583fb" #openweathermap API key

m = Map(center=(52, 10), zoom=5, basemap=basemaps.Hydda.Full)
maps = {'Hydda' : basemaps.Hydda.Full,
        'Esri' : basemaps.Esri.DeLorme}

header = HTML("<h1>Fictional World Weather</h1>", layout=Layout(height='auto'))
header.style.text_align='center'
basemap_selector = Dropdown( options = list(maps.keys()),
                            layout=Layout(width='auto'))

heatmap_selector = Dropdown(options=('Temperature', 'Precipitation'),
                            layout=Layout(width='auto'))

basemap_selector.value = 'Hydda'
m.layout.height='600px'

security_1 = np.cumsum(np.random.randn(150)) + 100.

dates = date_range(start='01-01-2007', periods=150)

dt_x = bq.DateScale()
sc_y = bq.LinearScale()

time_series = bq.Lines(x=dates, y=security_1, scales={'x': dt_x, 'y': sc_y})
ax_x = bq.Axis(scale=dt_x)
ax_y = bq.Axis(scale=sc_y, orientation='vertical')

fig = bq.Figure(marks=[time_series], axes=[ax_x, ax_y],
                fig_margin=dict(top=0, bottom=80, left=30, right=20))
In [18]:
m.layout.width='auto'
m.layout.height='auto'
fig.layout.width='auto'
fig.layout.height='auto'

out = HTML(
    value='',
    layout=Layout(width='auto', height='auto')
)

AppLayout(center=m, 
          header=header,
          left_sidebar=VBox([Label("Basemap:"),
                             basemap_selector,
                             Label("Overlay:"),
                             heatmap_selector]),
          right_sidebar=fig,
          footer=out,
          pane_widths=['80px', 1, 1],
          pane_heights=['80px', 4, 1],
          height='600px',
          grid_gap="30px")
In [19]:
rows = []
X, Y = np.mgrid[-90:90:10j, -180:180:20j]
X = X.flatten()
Y = Y.flatten()

temps = np.random.randn(200, 150)*0.5
In [20]:
from datetime import datetime
import random
In [21]:
def add_log(msg):
    max_rows = 3
    rows.append(msg)
    if len(rows) > max_rows:
        rows.pop(0)
    return '<h4>Activity log</h4><ul>{}</ul>'.format('<li>'.join([''] + rows))

def generate_temp_series(x, y):
    if heatmap_selector.value == 'Precipitation':
        temp = np.cumsum(np.random.randn(150)) + 100.
    elif heatmap_selector.value == 'Temperature':
        dist = np.sqrt((X - x)**2 + (Y-y)**2) / 100
        dist = dist.max() - dist
        dist[dist > np.percentile(dist, 5)] = 0
        temp = np.cumsum(np.dot(dist, temps)+0.05) + 20 - np.abs(x) / 2
    time_series.y = temp
    
def handle_interaction(**kwargs):
    if kwargs['type'] == 'click':
        generate_temp_series(*kwargs['coordinates'])
        msg = '%s Selected coordinates: %s, Temp: %d C Precipitation: %d mm\n' % (
            datetime.now(), kwargs['coordinates'], random.randint(-20, 20), random.randint(0, 100))
        out.value = add_log(msg)

m.on_interaction(handle_interaction) 

def on_map_selected(change):
    m.layers = [basemap_to_tiles(maps[basemap_selector.value]), weather_maps[heatmap_selector.value]]
    
basemap_selector.observe(on_map_selected, names='value')
heatmap_selector.observe(on_map_selected, names='value')
In [22]:
temp = TileLayer(min_zoom=1, max_zoom=18, url='https://tile.openweathermap.org/map/temp_new/{z}/{x}/{y}.png?appid='+OWM_API_KEY, name='owm', attribute='me')
precipitation = TileLayer(min_zoom=1, max_zoom=18, url='https://tile.openweathermap.org/map/precipitation_new/{z}/{x}/{y}.png?appid='+OWM_API_KEY, name='owm', attribute='me')
In [23]:
weather_maps = {'Temperature' : temp,
                'Precipitation' : precipitation}

m.add_layer(weather_maps[heatmap_selector.value])

The End