Skip to content

Commit

Permalink
Cleaned up dashboard notebook
Browse files Browse the repository at this point in the history
  • Loading branch information
philippjfr committed Apr 18, 2016
1 parent 95d8900 commit 4f1c6e4
Showing 1 changed file with 172 additions and 41 deletions.
213 changes: 172 additions & 41 deletions notebooks/Dashboard_Demo.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand All @@ -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'."
]
Expand All @@ -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)"
]
},
{
Expand All @@ -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')"
]
},
Expand All @@ -130,9 +154,9 @@
"dashboard": {
"layout": {
"col": 0,
"height": 33,
"height": 36,
"row": 7,
"width": 11
"width": 12
}
}
}
Expand All @@ -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",
Expand Down

0 comments on commit 4f1c6e4

Please sign in to comment.