{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Introduction to Visualization" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In the previous step of the tutorial we made some plots using `hvplot`, which provides interactive plots using a syntax similar to the Pandas `.plot()` method. In addition to Pandas, `hvPlot` supports XArray, Dask, GeoPandas, and a variety of other libraries. The result of an `hvplot` call is a `holoviews` object. This might seem a little mysterious, so we'll take a minute to show how this works. In this tutorial step we'll use generated data for simplicity." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import numpy as np\n", "import pandas as pd\n", "\n", "index = pd.date_range('1/1/2000', periods=1000)\n", "\n", "np.random.seed(11) # seeding the state to make the output identical each time\n", "data = np.random.randn(1000, 4)\n", "\n", "df = pd.DataFrame(data, index=index, columns=list('ABCD')).cumsum()\n", "\n", "df.head()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Use `hvplot` to product an interactively explorable plot with panning, zooming, hovering, and clickable/selectable legends:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import hvplot.pandas\n", "\n", "df.hvplot()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Exercise: Scroll in and out of the plot, click on an item in the legend, save a png" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Selection\n", "\n", "To inspect this plot more closely we can assign it to a variable and print that variable. We'll see that we in fact have a holoviews object of type `NdOverlay` and subtype `Curve`. " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "plot = df.hvplot()\n", "print(plot)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "But what does that mean? What we got out of hvplot was actually a mapping. " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Exercise: Use plot.keys() to inspect the keys of the mapping." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can select just one of the variables from the mapping just like you would from a dictionary:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "plot['A']" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Exercise: select a different label from the plot." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can create an overlay of just a few of the plots using the `*` operator" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "plot['B'] * plot['C']" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Subplots\n", "\n", "We can also switch it around so that instead of having all the plots overlayed, we can display them next to each other. For this we will use the '+' operator. Note that we also specified that there should only be one column, otherwise they would be added row-wise. " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "(plot['B'] + plot['C']).cols(1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Another way to achieve a similar result is to use the `subplots` keyword argument in `hvplot`. " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "df.hvplot(subplots=True, width=300).cols(2)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Exercise: Try to create something other than a line plot. Perhaps a scatter - df.hvplot.scatter(). \n", "# Challenge: Use tab completion to explore other plot types." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Visualizing images" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In the [Data Ingestion](01_Data_Ingestion.ipynb) tutorial, we saw how you can view Landsat imagery loaded with intake. First let us import `intake` and `hvplot.xarray` to load `hvplot` support for `xarray`:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import intake\n", "import hvplot.xarray" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now we can open the catalog and read in our data for Landsat 5 and 8. We'll be using the small versions in this tutorial, but feel free to change them to `cat.landsat_5` and `cat.landsat_8` to use the large versions instead." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "cat = intake.open_catalog('../catalog.yml')\n", "landsat_5 = cat.landsat_5_small.read_chunked()\n", "landsat_8 = cat.landsat_8_small.read_chunked()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Using `geo=True` in `hvplot`, we can ensure the appropriate coordinate reference system is used. In the next cell, we use this along with `cmap='fire'` to change the color map:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "landsat_5.hvplot(x='x', y='y', rasterize=True, geo=True, width=400, cmap='fire')" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Exercise: Try adjusting the width and adding a height option to make the overall plot bigger or smaller." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The 'fire' colormap is one of the [*perceptually uniform colormaps*](https://arxiv.org/abs/1509.03700) provided by [colorcet](http://colorcet.pyviz.org/). These colormaps are especially designed to help reveal features of the data that may be lost when using colormaps that are not perceptually uniform.\n", "\n", "## Combining images with `+`\n", "\n", "In the same way you can combine curves with `+` (as shown above using data loaded from a pandas DataFrame), you can do the same using images created from `xarray` objects.\n", "\n", "In the next cell, we use different colormaps for the Landsat 5 and Landsat 8 data, datashade them and position them next to each other:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "landsat_5_plot = landsat_5.hvplot(x='x', y='y', width=300, datashade=True, geo=True, cmap='Reds')\n", "landsat_8_plot = landsat_8.hvplot(x='x', y='y', width=300, datashade=True, geo=True, cmap='Blues')\n", "landsat_5_plot + landsat_8_plot" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "As `datashade=True`, the plots refresh with the available data when the zoom tool is used. Note that the plots have linked axes making comparison between plots easier. Note that the plots will only update to show higher resolution if a live Python process is running; on a web site zooming will only ever show the original set of pixels, getting larger on a zoom rather than revealing more data as you'll see if Python is available.\n", "\n", "hvPlot also supports a large range of plot types and options not shown here. A more detailed description of visualization options will follow in the [Data Visualization](05_Data_Visualization.ipynb) tutorial. See the [hvplot.pyviz.org](https://hvplot.pyviz.org) website for further details, and [holoviews.org](http://holoviews.org), [geoviews.org](http://geoviews.org), and [datashader.org](http://datashader.org) for information about the underlying functionality and advanced usage. You can also work through the extensive tutorials at [pyviz.org](http://pyviz.org)" ] } ], "metadata": { "language_info": { "name": "python", "pygments_lexer": "ipython3" } }, "nbformat": 4, "nbformat_minor": 2 }