From 6cdaf48defadb199fddfe58d3fbf1e6c75e43b15 Mon Sep 17 00:00:00 2001 From: jlstevens Date: Mon, 18 Apr 2016 01:08:41 +0100 Subject: [PATCH] Added doc/Introductory_Tutorial.ipynb notebook --- doc/Introductory_Tutorial.ipynb | 386 ++++++++++++++++++++++++++++++++ 1 file changed, 386 insertions(+) create mode 100644 doc/Introductory_Tutorial.ipynb diff --git a/doc/Introductory_Tutorial.ipynb b/doc/Introductory_Tutorial.ipynb new file mode 100644 index 0000000..24ce597 --- /dev/null +++ b/doc/Introductory_Tutorial.ipynb @@ -0,0 +1,386 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The Iris cubes used in this notebook are publicly available in the [``SciTools/iris-sample-data``](https://github.com/SciTools/iris-sample-data) repository. This notebook is based on the user story described in [Issue #7](https://github.com/CubeBrowser/cube-explorer/issues/7) with the following [image](http://www.wetterzentrale.de/wz/pics/Recm1201.gif) suggested for inspiration." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "import datetime\n", + "import iris\n", + "import numpy as np\n", + "import holoviews as hv\n", + "import holocube as hc\n", + "from cartopy import crs\n", + "from cartopy import feature as cf\n", + "hv.notebook_extension()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Setting some notebook-wide options" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's start by setting some normalization options (discussed below) and always enable colorbars for the elements we will be displaying:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "iris.FUTURE.strict_grib_load = True\n", + "%opts Image {+framewise} [colorbar=True] Contours [colorbar=True] {+framewise} Curve [xrotation=60]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Note that it is easy to set global defaults for a project allowing any suitable settings can be made into a default on a per-element basis. Now lets specify the maximum number of frames we will be displaying:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%output max_frames=1000 " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "
When working on a live server append ``widgets='live'`` to the line above for greatly improved performance and memory usage
\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Loading our first cube" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Here is the summary of the first cube containing some surface temperature data:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "iris_cube = iris.load_cube(iris.sample_data_path('GloSea4', 'ensemble_001.pp'))\n", + "iris_cube.coord('latitude').guess_bounds()\n", + "iris_cube.coord('longitude').guess_bounds()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "print iris_cube.summary()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now we can wrap this Iris cube in a ``HoloCube``:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "surface_temperature = hc.HoloCube(iris_cube)\n", + "surface_temperature" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# A Simple example" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Here is a simple example of viewing the ``surface_temperature`` cube over time with a single line of code. In HoloViews, this datastructure is a ``HoloMap`` of ``Image`` elements:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "surface_temperature.to.image(['longitude', 'latitude'])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "You can drag the slider to view the surface temperature at different times. Here is how you can view the values of time in the cube via the HoloViews API:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "surface_temperature.dimension_values('time')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The times shown in the slider are long making the text rather small. We can use the fact that all times are recorded in the year 2011 on the 16th of each month to shorten these dates. Defining how all dates should be formatted as follows will help with readability:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "hv.Dimension.type_formatters[datetime.datetime] = \"%m/%y %Hh\"" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now let us load a cube showing the pre-industrial air temperature:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "air_temperature = hc.HoloCube(iris.load_cube(iris.sample_data_path('pre-industrial.pp')),\n", + " group='Pre-industrial air temperature')\n", + "air_temperature.data.coord('longitude').guess_bounds()\n", + "air_temperature.data.coord('latitude').guess_bounds()\n", + "air_temperature # Use air_temperature.data.summary() to see the Iris summary (.data is the Iris cube)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Note that we have the ``air_temperature`` available over ``longitude`` and ``latitude`` but *not* the ``time`` dimensions. As a result, this cube is a single frame when visualized as a temperature map." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "(surface_temperature.to.image(['longitude', 'latitude']) + air_temperature.to.image(['longitude', 'latitude']))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Next is a fairly involved example that plots data side-by-side in a ``Layout`` without using the ``+`` operator. \n", + "\n", + "This shows how complex plots can be generated with little code and also demonstrates how different HoloViews elements can be combined together. In the following visualization, the curve is a sample of the ``surface_temperature`` at longitude and latitude *(0,10)*:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%%opts Layout [fig_inches=(12,7)] Curve [aspect=2 xticks=4 xrotation=20] Points (color=2)\n", + "# Sample the surface_temperature at (0,10)\n", + "temp_curve = surface_temperature.to.curve('time', dynamic=True)[0, 10]\n", + "# Show surface_temperature and air_temperature with Point (0,10) marked\n", + "temp_maps = [cb.to.image(['longitude', 'latitude']) * hc.Points([(0,10)]) \n", + " for cb in [surface_temperature, air_temperature]]\n", + "# Show everything in a two column layout\n", + "hv.Layout(temp_maps + [temp_curve]).cols(2).display('all')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Overlaying data and normalization" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Lets view the surface temperatures together with the global coastline:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "cf.COASTLINE.scale='1000m'" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%%opts Image [projection=crs.Geostationary()] (cmap='Greens')\n", + "surface_temperature.to.image(['longitude', 'latitude']) * hc.GeoFeature(cf.COASTLINE)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Notice that every frame uses the full dynamic range of the Greens color map. This is because normalization is set to ``+framewise`` at the top of the notebook which means every frame is normalized independently. \n", + "\n", + "To control normalization, we need to decide on the normalization limits. Let's see the maximum temperature in the cube:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "max_surface_temp = surface_temperature.data.data.max()\n", + "max_surface_temp" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%%opts Image [projection=crs.Geostationary()] (cmap='Greens')\n", + "# Declare a humidity dimension with a range from 0 to 0.01\n", + "surface_temp_dim = hv.Dimension('surface_temperature', range=(300, max_surface_temp))\n", + "# Use it to declare the value dimension of a HoloCube\n", + "(hc.HoloCube(surface_temperature, vdims=[surface_temp_dim]).to.image(['longitude', 'latitude']) * hc.GeoFeature(cf.COASTLINE))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "By specifying the normalization range we can reveal different aspects of the data. In the example above we can see a warming effect over time as the dark green areas close to the bottom of the normalization range (200K) vanish. Values outside this range are clipped to the ends of the color map." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Lastly, here is a demo of a conversion from ``surface_temperature`` to ``Contours``:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%%opts Contours [levels=10]\n", + "(surface_temperature.to.contours(['longitude', 'latitude']) * hc.GeoFeature(cf.COASTLINE))" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.11" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +}