Basic Plotting

Previous sections have focused on putting various simple types of data together in notebooks and deployed servers, but most people will want to include plots as well. In this section, we'll focus on one of the simplest (but still powerful) ways to get a plot.

If you have tried to visualize a pandas.DataFrame before, then you have likely encountered the Pandas .plot() API. This basic plotting interface uses Matplotlib to render static PNGs or SVGs in a Jupyter notebook using theinline backend (or interactive figures via %matplotlib notebook or %matplotlib widget) and for exporting from Python, with a command that can be as simple as df.plot() for a DataFrame with one or two columns.

The Pandas .plot() API has emerged as a de-facto standard for high-level plotting APIs in Python, and is now supported by many different libraries that use other underlying plotting engines to provide additional power and flexibility. Thus learning this API allows you to access capabilities provided by a wide variety of underlying tools, with relatively little additional effort. The libraries currently supporting this API include:

  • Pandas -- Matplotlib-based API included with Pandas. Static or interactive output in Jupyter notebooks.
  • xarray -- Matplotlib-based API included with xarray, based on pandas .plot API. Static or interactive output in Jupyter notebooks.
  • hvPlot -- HoloViews and Bokeh-based interactive plots for Pandas, GeoPandas, xarray, Dask, Intake, and Streamz data.
  • Pandas Bokeh -- Bokeh-based interactive plots, for Pandas, GeoPandas, and PySpark data.
  • Cufflinks -- Plotly-based interactive plots for Pandas data.
  • Plotly Express -- Plotly-Express-based interactive plots for Pandas data; only partial support for the .plot API keywords
  • PdVega -- Vega-lite-based, JSON-encoded interactive plots for Pandas data.

In this notebook we'll explore what is possible with the default .plot API and demonstrate the additional capabilities of .hvplot, using the same tabular dataset of earthquakes and other seismological events queried from the USGS Earthquake Catalog using its API as in previous sections. Of course, this particular dataset is just an example; the same approach can be used with just about any tabular dataset.

Read in the data

Here we'll read in the data using Dask, which works well with a relatively large dataset like this (2.1 million rows). We'll use .persist() to bring the whole dataset into main memory (which should be feasible on any recent machine) for higher performance:

In [1]:
import dask.dataframe as dd
In [2]:
df = dd.read_parquet('../data/earthquakes.parq').persist()
df.time = df.time.astype('datetime64[ns]')
depth depthError dmin gap horizontalError id latitude locationSource longitude mag ... magSource magType net nst place rms status time type updated
0 7.800 1.400 0.09500 245.14 NaN nn00001936 37.1623 nn -116.6037 0.60 ... nn ml nn 5.0 Nevada 0.0519 reviewed 2000-01-31 23:52:00.619 earthquake 2018-04-24T22:22:44.135Z
1 4.516 0.479 0.05131 52.50 NaN ci9137218 34.3610 ci -116.1440 1.72 ... ci mc ci 0.0 26km NNW of Twentynine Palms, California 0.1300 reviewed 2000-01-31 23:44:54.060 earthquake 2016-02-17T11:53:52.643Z
2 33.000 NaN NaN NaN NaN usp0009mwt 10.6930 trn -61.1620 2.10 ... trn md us NaN Trinidad, Trinidad and Tobago NaN reviewed 2000-01-31 23:28:38.420 earthquake 2014-11-07T01:09:23.016Z
3 33.000 NaN NaN NaN NaN usp0009mws -1.2030 us -80.7160 4.50 ... us mb us NaN near the coast of Ecuador 0.6000 reviewed 2000-01-31 23:05:22.010 earthquake 2014-11-07T01:09:23.014Z
4 7.200 0.900 0.11100 202.61 NaN nn00001935 38.7860 nn -119.6409 1.40 ... nn ml nn 5.0 Nevada 0.0715 reviewed 2000-01-31 22:56:50.996 earthquake 2018-04-24T22:22:44.054Z

5 rows × 22 columns

Using Pandas .plot

The first thing that we'd like to do with this data is visualize the locations of every earthquake. So we would like to make a scatter or points plot where x='longitude' and y='latitude'.

If you are familiar with the pandas.plot API, you might expect to execute df.plot.scatter(x='longitude', y='latitude'). Feel free to try this out in a new cell, but it will throw an error: AttributeError: 'DataFrame' object has no attribute 'plot'. Since we have a Dask dataframe rather than a Pandas dataframe, we need to first convert it to Pandas to use .plot. In order to make the data more manageable for now, we'll briefly use just a fraction (1%) of it and call that small_df.

In [3]:
%matplotlib inline
In [4]:
small_df = df.sample(frac=.01).compute()
(21165, 22)

Now we have a smaller dataset with just 21k earthquakes. We can use that to test out our visualizations before ramping back up to the full dataset.

In [5]:
small_df.plot.scatter(x='longitude', y='latitude');

Using .hvplot

As you can see above, the Pandas API gives you a usable plot very easily, where you can start to see the structure of the edges of the plates (which in some cases correspond with the edges of the continents and in others are between two continents). You can make a very similar plot with the same arguments using hvplot.

In [6]:
import hvplot.pandas