From 4f1c6e408ca2ac545f14105ff80656dc7e38853c Mon Sep 17 00:00:00 2001
From: Philipp Rudiger
Date: Mon, 18 Apr 2016 08:32:46 +0100
Subject: [PATCH] Cleaned up dashboard notebook
---
notebooks/Dashboard_Demo.ipynb | 213 ++++++++++++++++++++++++++-------
1 file changed, 172 insertions(+), 41 deletions(-)
diff --git a/notebooks/Dashboard_Demo.ipynb b/notebooks/Dashboard_Demo.ipynb
index eb57352..ccba70b 100644
--- a/notebooks/Dashboard_Demo.ipynb
+++ b/notebooks/Dashboard_Demo.ipynb
@@ -18,8 +18,7 @@
"import numpy as np\n",
"import holoviews as hv\n",
"import holocube as hc\n",
- "from matplotlib.cm import cmap_d\n",
- "from cartopy import crs as ccrs\n",
+ "\n",
"from cartopy import feature as cf\n",
"from paramnb import NbParams, FileSelector\n",
"\n",
@@ -30,7 +29,13 @@
},
{
"cell_type": "markdown",
- "metadata": {},
+ "metadata": {
+ "urth": {
+ "dashboard": {
+ "hidden": true
+ }
+ }
+ },
"source": [
"Declaring a set of widgets using paramNB is as simply as declaring a Parameterized class. Here we declare a ``CubeLoader`` class with a ``FileSelector`` parameter, a cache and a load method, which will load cubes from a file on disk. The ``NbParams`` function accepts the ``CubeLoader`` instance and generates a dropdown widget for the ``cube_path`` from it. By declaring a callback we can tell it to load the file from disk (or the cache) whenever the user executes the widget. Finally we can declare the ``execute`` mode, which allows declaring no execution with ``execute=None`` or adds a button to execute the 'next' cell or all cells 'below'."
]
@@ -56,26 +61,24 @@
"class CubeLoader(param.Parameterized):\n",
" \n",
" cube_path = FileSelector(default='files/*.pp')\n",
+ "\n",
+ " cache = {}\n",
+ " cubes = None\n",
" \n",
- " def __init__(self, **params):\n",
- " super(CubeLoader, self).__init__(**params)\n",
- " self.cache = {}\n",
- " self.cubes = None\n",
- " \n",
- " def load(self, cube_loader):\n",
- " if self.cube_path not in self.cache:\n",
- " cubelist = iris.load(self.cube_path)\n",
+ " @classmethod\n",
+ " def load(cls, cube_loader):\n",
+ " if cls.cube_path not in cls.cache:\n",
+ " cubelist = iris.load(cls.cube_path)\n",
" for c in cubelist:\n",
" c.coord('grid_longitude').guess_bounds()\n",
" c.coord('grid_latitude').guess_bounds()\n",
- " self.cache[self.cube_path] = cubelist\n",
+ " cls.cache[cls.cube_path] = cubelist\n",
" else:\n",
- " cubelist = self.cache[self.cube_path]\n",
+ " cubelist = cls.cache[cls.cube_path]\n",
" cubes = {cb.vdims[0].name:cb for cb in [hc.HoloCube(c) for c in cubelist]} # Load cubes into dictionary\n",
- " self.cubes = {k:v for k,v in cubes.items() if k!='unknown'} # Filter as desired\n",
+ " cls.cubes = {k:v for k,v in cubes.items() if k!='unknown'} # Filter as desired\n",
"\n",
- "cube_loader = CubeLoader()\n",
- "NbParams(cube_loader, execute='next', callback=cube_loader.load)"
+ "NbParams(CubeLoader, execute='next', callback=CubeLoader.load)"
]
},
{
@@ -96,28 +99,49 @@
},
"outputs": [],
"source": [
- "# Next we declare a more complex ``CubeBrowser`` class, which will define the various options on what to display and how to display it.\n",
- "# We add parameters to control the cmap, quantity, element and projection and populate these with useful options.\n",
- "\n",
- "def all_subclasses(cls):\n",
- " return cls.__subclasses__() + [g for s in cls.__subclasses__()\n",
- " for g in all_subclasses(s)]\n",
+ "from cartopy import crs as ccrs\n",
+ "from matplotlib.cm import cmap_d\n",
"\n",
- "projections = {crs.__name__: crs for crs in all_subclasses(ccrs.CRS)\n",
- " if hasattr(crs, '_as_mpl_axes') and not crs.__name__[0] == '_'}\n",
+ "projections = {k: crs for k, crs in param.concrete_descendents(ccrs.CRS).items()\n",
+ " if hasattr(crs, '_as_mpl_axes') and not k[0] == '_'}\n",
"\n",
"class CubeBrowser(param.Parameterized):\n",
+ " \"\"\"\n",
+ " CubeBrowser defines a small example GUI to demonstrate\n",
+ " how to define a small set of widgets to control plotting\n",
+ " of an iris Cube. It exposes control over the colormap,\n",
+ " the quantity to be plotted, the element to plot it with\n",
+ " and the projection to plot it on.\n",
+ " \"\"\"\n",
"\n",
- " cmap = param.ObjectSelector(default='viridis', objects=list(cmap_d.keys()))\n",
+ " cmap = param.ObjectSelector(default='viridis',\n",
+ " objects=list(cmap_d.keys()))\n",
"\n",
- " quantity = param.ObjectSelector(default=cube_loader.cubes.keys()[0], objects=list(cube_loader.cubes.keys()))\n",
+ " quantity = param.ObjectSelector(default=CubeLoader.cubes.keys()[0],\n",
+ " objects=list(CubeLoader.cubes.keys()))\n",
"\n",
- " element = param.ObjectSelector(default=hc.Image, objects=[hc.Image, hc.Contours])\n",
+ " element = param.ObjectSelector(default=hc.Image,\n",
+ " objects=[hc.Image, hc.Contours])\n",
"\n",
- " projection = param.ObjectSelector(default='PlateCarree', objects=list(projections.keys()))\n",
+ " projection = param.ObjectSelector(default='default',\n",
+ " objects=['default']+sorted(projections.keys()))\n",
" \n",
" cache = {}\n",
"\n",
+ " @classmethod\n",
+ " def view(cls):\n",
+ " key = (cls.quantity, cls.element)\n",
+ " if key in CubeBrowser.cache:\n",
+ " converted = cls.cache[key]\n",
+ " else:\n",
+ " holocube = CubeLoader.cubes[cls.quantity]\n",
+ " converted = holocube.to(cls.element, ['grid_longitude', 'grid_latitude'], dynamic=True)\n",
+ " cls.cache[key] = converted\n",
+ " styled = converted(style={cls.element.name: dict(cmap=cls.cmap)})\n",
+ " projection = projections[cls.projection]() if cls.projection != 'default' else None\n",
+ " projected = styled({'Image': dict(plot=dict(projection=projection))}) if projection else styled\n",
+ " return (projected * hc.GeoFeature(cf.COASTLINE)(plot=dict(scale='50m')))\n",
+ "\n",
"NbParams(CubeBrowser, execute='next')"
]
},
@@ -130,9 +154,9 @@
"dashboard": {
"layout": {
"col": 0,
- "height": 33,
+ "height": 36,
"row": 7,
- "width": 11
+ "width": 12
}
}
}
@@ -141,21 +165,128 @@
"source": [
"# Finally we can declare a cell which uses the settings defined via the widgets to render the requested plot.\n",
"# We simply look up the correct cube, convert it to the desired Element type and then display it with the requested options.\n",
- "\n",
- "key = (CubeBrowser.quantity, CubeBrowser.element)\n",
- "if key in CubeBrowser.cache:\n",
- " converted = CubeBrowser.cache[key]\n",
- "else:\n",
- " holocube = cube_loader.cubes[cube_browser.quantity]\n",
- " converted = holocube.to(cube_browser.element, ['grid_longitude', 'grid_latitude'], dynamic=True)\n",
- " CubeBrowser.cache[key] = converted\n",
- "styled = converted(style={cube_browser.element.name: dict(cmap=cube_browser.cmap)})\n",
- "projection = projections[cube_browser.projection]()\n",
- "(styled * hc.GeoFeature(cf.COASTLINE)(plot=dict(scale='50m'))(plot=dict(projection=projection)))"
+ "CubeBrowser.view()"
]
}
],
"metadata": {
+ "environment": {
+ "dependencies": [
+ "appnope=0.1.0=py27_0",
+ "backports=1.0=py27_0",
+ "backports_abc=0.4=py27_0",
+ "biggus=0.13.0=py27_0",
+ "cartopy=0.13.1=np110py27_0",
+ "cf_units=1.1=py27_0",
+ "configparser=3.5.0b2=py27_1",
+ "curl=7.45.0=0",
+ "cycler=0.10.0=py27_0",
+ "cython=0.24=py27_0",
+ "decorator=4.0.9=py27_0",
+ "ecmwf_grib=1.14.2=np110py27_0",
+ "entrypoints=0.2=py27_1",
+ "freetype=2.5.5=0",
+ "funcsigs=1.0.0=py27_0",
+ "geos=3.4.2=4",
+ "hdf5=1.8.15.1=2",
+ "ipykernel=4.3.1=py27_0",
+ "ipython=4.1.2=py27_2",
+ "ipython_genutils=0.1.0=py27_0",
+ "ipywidgets=4.1.1=py27_0",
+ "iris=1.9.2=np110_0",
+ "jasper=1.900.1=5",
+ "jbig=2.1=0",
+ "jinja2=2.8=py27_0",
+ "jpeg=8d=1",
+ "jsonschema=2.4.0=py27_0",
+ "jupyter=1.0.0=py27_2",
+ "jupyter_client=4.2.2=py27_0",
+ "jupyter_console=4.1.1=py27_0",
+ "jupyter_core=4.1.0=py27_0",
+ "libmo_unpack=3.0=3",
+ "libnetcdf=4.3.3.1=3",
+ "libpng=1.6.17=0",
+ "libtiff=4.0.6=1",
+ "libxml2=2.9.2=0",
+ "libxslt=1.1.28=2",
+ "lxml=3.6.0=py27_0",
+ "markupsafe=0.23=py27_0",
+ "matplotlib=1.5.1=np110py27_0",
+ "mistune=0.7.2=py27_1",
+ "mkl=11.3.1=0",
+ "mo_pack=0.2.0=np110py27_1",
+ "mock=2.0.0=py27_0",
+ "nbconvert=4.2.0=py27_0",
+ "nbformat=4.0.1=py27_0",
+ "netcdf4=1.2.2=np110py27_0",
+ "nose=1.3.7=py27_0",
+ "notebook=4.1.0=py27_2",
+ "numpy=1.10.4=py27_0",
+ "openssl=1.0.2g=0",
+ "owslib=0.10.3=py27_0",
+ "pandas=0.18.0=np111py27_0",
+ "path.py=8.2=py27_0",
+ "pbr=1.8.0=py27_0",
+ "pexpect=4.0.1=py27_0",
+ "pickleshare=0.5=py27_0",
+ "pillow=3.2.0=py27_0",
+ "pip=8.1.1=py27_1",
+ "proj.4=4.9.1=1",
+ "ptyprocess=0.5=py27_0",
+ "pyepsg=0.2.0=py27_0",
+ "pygments=2.1.3=py27_0",
+ "pyke=1.1.1=py27_2",
+ "pyparsing=2.0.3=py27_0",
+ "pyproj=1.9.4=py27_1",
+ "pyqt=4.11.4=py27_1",
+ "pyshp=1.2.3=py27_0",
+ "python=2.7.11=0",
+ "python-dateutil=2.5.2=py27_0",
+ "pytz=2016.3=py27_0",
+ "pyzmq=15.2.0=py27_0",
+ "qt=4.8.7=1",
+ "qtconsole=4.2.1=py27_0",
+ "readline=6.2=2",
+ "requests=2.9.1=py27_0",
+ "scipy=0.17.0=np110py27_0",
+ "setuptools=20.6.7=py27_0",
+ "shapely=1.5.13=np110py27_1",
+ "simplegeneric=0.8.1=py27_0",
+ "singledispatch=3.4.0.3=py27_0",
+ "sip=4.16.9=py27_0",
+ "six=1.10.0=py27_0",
+ "sqlite=3.9.2=0",
+ "ssl_match_hostname=3.4.0.2=py27_1",
+ "terminado=0.5=py27_1",
+ "tk=8.5.18=0",
+ "tornado=4.3=py27_0",
+ "traitlets=4.2.1=py27_0",
+ "udunits2=2.2.20=0",
+ "wheel=0.29.0=py27_0",
+ "xz=5.0.5=1",
+ "zlib=1.2.8=0",
+ {
+ "pip": [
+ "backports-abc==0.4",
+ "backports.ssl-match-hostname==3.4.0.2",
+ "cartopy (/Users/philippjfr/cartopy/lib)==0.14.0",
+ "cf-units==1.1",
+ "holocube (/Users/philippjfr/cube-explorer)==0.0.1",
+ "holoviews==1.4.3",
+ "ipython-genutils==0.1.0",
+ "iris (/Users/philippjfr/iris/lib)==1.10.0.dev0",
+ "jupyter-client==4.2.2",
+ "jupyter-console==4.1.1",
+ "jupyter-core==4.1.0",
+ "lancet-ioam==0.9.0",
+ "mo-pack==0.2.0",
+ "param==1.3.2",
+ "paramnb (/Users/philippjfr/paramnb)==0.0.1"
+ ]
+ }
+ ],
+ "name": "metoffice"
+ },
"hide_input": false,
"kernelspec": {
"display_name": "Python 2",