Weather map

Weather map#

This notebook shows an example of use of the AppLayout template, which is documented in Layout Templates notebook. You can check that notebook for further explanation.

This notebook depends on extra packages:

  • bqplot - widget-based plotting library,

  • ipyleaflet - cartography widget based on leaflet.js

If you also would like to see a color weather map, you will need to obtain an API key from OpenWeatherMap.

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

To see map overlays obtain your API key free of charge from OpenWeatherMap and paste it below.

OWM_API_KEY = "PASTE_YOUR_OWM_API_KEY_HERE" #openweathermap API key
m = Map(center=(52, 10), zoom=5, basemap=basemaps.OpenStreetMap.Mapnik)
maps = {'Mapnik' : basemaps.OpenStreetMap.Mapnik,
        'Esri' : basemaps.Esri.DeLorme}
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
File /opt/hostedtoolcache/Python/3.12.7/x64/lib/python3.12/site-packages/xyzservices/lib.py:45, in Bunch.__getattr__(self, key)
     44 try:
---> 45     return self.__getitem__(key)
     46 except KeyError as err:

KeyError: 'DeLorme'

The above exception was the direct cause of the following exception:

AttributeError                            Traceback (most recent call last)
Cell In[5], line 2
      1 maps = {'Mapnik' : basemaps.OpenStreetMap.Mapnik,
----> 2         'Esri' : basemaps.Esri.DeLorme}

File /opt/hostedtoolcache/Python/3.12.7/x64/lib/python3.12/site-packages/xyzservices/lib.py:47, in Bunch.__getattr__(self, key)
     45     return self.__getitem__(key)
     46 except KeyError as err:
---> 47     raise AttributeError(key) from err

AttributeError: 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'))
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Cell In[6], line 3
      1 header = HTML("<h1>Fictional World Weather</h1>", layout=Layout(height='auto'))
      2 header.style.text_align='center'
----> 3 basemap_selector = Dropdown( options = list(maps.keys()),
      4                             layout=Layout(width='auto'))
      6 heatmap_selector = Dropdown(options=('Temperature', 'Precipitation'),
      7                             layout=Layout(width='auto'))

NameError: name 'maps' is not defined
basemap_selector.value = 'Mapnik'
m.layout.height='600px'
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Cell In[7], line 1
----> 1 basemap_selector.value = 'Mapnik'
      2 m.layout.height='600px'

NameError: name 'basemap_selector' is not defined
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))
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")
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Cell In[11], line 4
      1 AppLayout(center=m, 
      2           header=header,
      3           left_sidebar=VBox([Label("Basemap:"),
----> 4                              basemap_selector,
      5                              Label("Overlay:"),
      6                              heatmap_selector]),
      7           right_sidebar=fig,
      8           footer=out,
      9           pane_widths=['80px', 1, 1],
     10           pane_heights=['80px', 4, 1],
     11           height='600px',
     12           grid_gap="30px")

NameError: name 'basemap_selector' is not defined
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
from datetime import datetime
import random
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')
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Cell In[18], line 30
     27 def on_map_selected(change):
     28     m.layers = [basemap_to_tiles(maps[basemap_selector.value]), weather_maps[heatmap_selector.value]]
---> 30 basemap_selector.observe(on_map_selected, names='value')
     31 heatmap_selector.observe(on_map_selected, names='value')

NameError: name 'basemap_selector' is not defined
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')
weather_maps = {'Temperature' : temp,
                'Precipitation' : precipitation}
m.add_layer(weather_maps[heatmap_selector.value])
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Cell In[21], line 1
----> 1 m.add_layer(weather_maps[heatmap_selector.value])

NameError: name 'heatmap_selector' is not defined