⚠️ IMPORTANT NOTICE ⚠️
This site is ARCHIVED and will NO LONGER BE UPDATED.
For updated Tutorial material, please visit the Pythia landsat-ml cookbook.
For Topic Examples, head over to the HoloViz Examples website.

Introduction to Visualization

Right click to download this notebook from GitHub.


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.

In [1]:
import numpy as np
import pandas as pd

index = pd.date_range('1/1/2000', periods=1000)

np.random.seed(11)  # seeding the state to make the output identical each time
data = np.random.randn(1000, 4)

df = pd.DataFrame(data, index=index, columns=list('ABCD')).cumsum()

df.head()
Out[1]:
A B C D
2000-01-01 1.749455 -0.286073 -0.484565 -2.653319
2000-01-02 1.741170 -0.605704 -1.021194 -2.337916
2000-01-03 2.162221 -1.671307 -1.907434 -2.813649
2000-01-04 2.851903 -1.110115 -3.212983 -3.933125
2000-01-05 3.588741 0.464519 -3.244058 -4.616571

Use hvplot to product an interactively explorable plot with panning, zooming, hovering, and clickable/selectable legends:

In [2]:
import hvplot.pandas

df.hvplot()
Out[2]:
In [3]:
# Exercise: Scroll in and out of the plot, click on an item in the legend, save a png

Selection

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.

In [4]:
plot = df.hvplot()
print(plot)
:NdOverlay   [Variable]
   :Curve   [index]   (value)

But what does that mean? What we got out of hvplot was actually a mapping.

In [5]:
# Exercise: Use plot.keys() to inspect the keys of the mapping.

We can select just one of the variables from the mapping just like you would from a dictionary:

In [6]:
plot['A']
Out[6]:
In [7]:
# Exercise: select a different label from the plot.

We can create an overlay of just a few of the plots using the * operator

In [8]:
plot['B'] * plot['C']
Out[8]:

Subplots

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.

In [9]:
(plot['B'] + plot['C']).cols(1)
Out[9]:

Another way to achieve a similar result is to use the subplots keyword argument in hvplot.

In [10]:
df.hvplot(subplots=True, width=300).cols(2)
Out[10]:
In [11]:
# Exercise: Try to create something other than a line plot. Perhaps a scatter - df.hvplot.scatter(). 
# Challenge: Use tab completion to explore other plot types.

Visualizing images

In the Data Ingestion 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:

In [12]:
import intake
import hvplot.xarray

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.

In [13]:
cat = intake.open_catalog('../catalog.yml')
landsat_5 = cat.landsat_5_small.read_chunked()
landsat_8 = cat.landsat_8_small.read_chunked()

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:

In [14]:
landsat_5.hvplot(x='x', y='y', rasterize=True, geo=True, width=400, cmap='fire')
Out[14]:
In [15]:
# Exercise: Try adjusting the width and adding a height option to make the overall plot bigger or smaller.

The 'fire' colormap is one of the perceptually uniform colormaps provided by colorcet. These colormaps are especially designed to help reveal features of the data that may be lost when using colormaps that are not perceptually uniform.

Combining images with +

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.

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:

In [16]:
landsat_5_plot = landsat_5.hvplot(x='x', y='y', width=300, datashade=True, geo=True, cmap='Reds')
landsat_8_plot = landsat_8.hvplot(x='x', y='y', width=300, datashade=True, geo=True, cmap='Blues')
landsat_5_plot + landsat_8_plot
Out[16]:

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.

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 tutorial. See the hvplot.pyviz.org website for further details, and holoviews.org, geoviews.org, and datashader.org for information about the underlying functionality and advanced usage. You can also work through the extensive tutorials at pyviz.org