{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "
\n", "\n", "
\n", "\"Unidata\n", "
\n", "\n", "

Matplotlib: Basics

\n", "

Unidata AMS 2021 Student Conference

\n", "\n", "
\n", "
\n", "\n", "---\n", "\n", "
\"Line
\n", "\n", "\n", "### Focuses\n", "\n", "* Create basic line and scatter plots.\n", "* Add labels and grid lines to a plot.\n", "* Draw multiple datasets on the same plot.\n", "\n", "\n", "### Objectives\n", "\n", "1. [Generate Test Data](#1.-Generate-Test-Data)\n", "1. [Create a Line Plot](#2.-Create-a-Line-Plot)\n", "1. [Add Axes Labels](#3.-Add-Axes-Labels)\n", "1. [Add a Title](#4.-Add-a-Title)\n", "1. [Create a Scatter Plot](#5.-Create-a-Scatter-Plot)\n", "1. [Plot Multiple Data Sets](#6.-Plot-Multiple-Data-Sets)\n", "1. [Change Display Settings](#7.-Change-Display-Settings)\n", "\n", "---" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Imports\n", "\n", "The first step is to set up the notebook so that matplotlib plots appear inline as images. Then we import the necessary packages for this notebook." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "%matplotlib inline\n", "import matplotlib.pyplot as plt\n", "import numpy as np" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 1. Generate Test Data\n", "\n", "Create some data to use while experimenting with plotting." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "times = np.array([ 93., 96., 99., 102., 105., 108., 111., 114., 117.,\n", " 120., 123., 126., 129., 132., 135., 138., 141., 144.,\n", " 147., 150., 153., 156., 159., 162.])\n", "temps = np.array([310.7, 308.0, 296.4, 289.5, 288.5, 287.1, 301.1, 308.3,\n", " 311.5, 305.1, 295.6, 292.4, 290.4, 289.1, 299.4, 307.9,\n", " 316.6, 293.9, 291.2, 289.8, 287.1, 285.8, 303.3, 310.])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Top\n", "\n", "---\n", "\n", "## 2. Create a Line Plot\n", "\n", "Matplotlib has two core objects: the **Figure** and the **Axes**. The Axes is an individual plot with an x-axis, a y-axis, labels, etc; it has all of the various plotting methods we use. A Figure holds one or more Axes on which we draw; think of the Figure as the level at which things are saved to files (e.g. PNG, SVG)\n", "\n", "Below the first line asks for a Figure 10 inches by 6 inches. Then obtain an Axes or subplot on the Figure. After that, call plot, with *times* as the data along the x-axis (independant values) and *temps* as the data along the y-axis (the dependant values)." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Create a figure\n", "fig = plt.figure(figsize=(10, 6))\n", "\n", "# Ask, out of a 1x1 grid, the first axes.\n", "ax = fig.add_subplot(1, 1, 1)\n", "\n", "# Plot times as x-variable and temperatures as y-variable\n", "ax.plot(times, temps)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Top\n", "\n", "---\n", "\n", "## 3. Add Axes Labels" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Add some labels to the plot\n", "ax.set_xlabel('Time')\n", "ax.set_ylabel('Temperature')\n", "\n", "# Prompt the notebook to re-display the figure after we modify it\n", "fig" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Top\n", "\n", "---\n", "\n", "## 4. Add a Title" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "ax.set_title('GFS Temperature Forecast', fontdict={'size':16})\n", "\n", "fig" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Top\n", "\n", "---\n", "\n", "## 5. Create a Scatter Plot\n", "\n", "Maybe it doesn't make sense to plot the data as a line plot, but with markers (a scatter plot). This can easily be done by setting the linestyle to none and specifying a marker type, size, color, etc." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "fig = plt.figure(figsize=(10, 6))\n", "ax = fig.add_subplot(1, 1, 1)\n", "\n", "# Specify no line with circle markers\n", "ax.plot(times, temps, linestyle='None', marker='o', markersize=5)\n", "\n", "ax.set_xlabel('Time')\n", "ax.set_ylabel('Temperature')\n", "ax.set_title('Temperature Scatter Plot')\n", "ax.grid(True)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Top\n", "\n", "---\n", "\n", "## 6. Plot Multiple Data Sets\n", "\n", "Switching back to the line plots, it is possible for multiple series of temperature data to be drawn on the same plot. When plotting, pass **label** in plot() to facilitate automatic creation. This is added with the legend call. Also add gridlines to the plot using the grid() call." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Set up more temperature data\n", "temps_1000 = np.array([316.0, 316.3, 308.9, 304.0, 302.0, 300.8, 306.2, 309.8,\n", " 313.5, 313.3, 308.3, 304.9, 301.0, 299.2, 302.6, 309.0,\n", " 311.8, 304.7, 304.6, 301.8, 300.6, 299.9, 306.3, 311.3])\n", "\n", "fig = plt.figure(figsize=(10, 6))\n", "ax = fig.add_subplot(1, 1, 1)\n", "\n", "# Plot two series of data\n", "# The label argument is used when generating a legend.\n", "ax.plot(times, temps, label='Temperature (surface)')\n", "ax.plot(times, temps_1000, label='Temperature (1000 mb)')\n", "\n", "# Add labels and title\n", "ax.set_xlabel('Time')\n", "ax.set_ylabel('Temperature')\n", "ax.set_title('Temperature Forecast')\n", "\n", "# Add gridlines\n", "ax.grid(True)\n", "\n", "# Add a legend to the upper left corner of the plot\n", "ax.legend(loc='upper left')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Top\n", "\n", "---\n", "\n", "## 7. Change Display Settings\n", "\n", "The display is not restricted to the default look of the plots, but rather style attributes can be overriden, such as **linestyle** and **color**. The color attribute can accept a wide array of options, such as red or blue or HTML color codes. In this example, use different shades of red taken from the Tableau color set in matplotlib, by using **tab:red** and **tab:orange** for color." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "fig = plt.figure(figsize=(10, 6))\n", "ax = fig.add_subplot(1, 1, 1)\n", "\n", "# Specify how our lines should look\n", "ax.plot(times, temps, color='tab:red', label='Temperature (surface)')\n", "ax.plot(times, temps_1000, color='tab:orange', linestyle='--',\n", " label='Temperature (isobaric level)')\n", "\n", "# Same as above\n", "ax.set_xlabel('Time')\n", "ax.set_ylabel('Temperature')\n", "ax.set_title('Temperature Forecast')\n", "ax.grid(True)\n", "ax.legend(loc='upper left')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Top\n", "\n", "---\n", "\n", "## See also\n", "\n", "Documentation for:\n", "\n", "* [matplotlib.pyplot](https://matplotlib.org/3.3.3/api/_as_gen/matplotlib.pyplot.html)\n", "* [matplotlib.pyplot.figure](https://matplotlib.org/3.3.3/api/_as_gen/matplotlib.pyplot.figure.html)\n", "* [matplotlib.pyplot.axes](https://matplotlib.org/3.3.3/api/_as_gen/matplotlib.pyplot.axes.html)\n", "\n", "\n", "### Related Notebooks\n", "\n", "* [Matplotlib: Intermediate](https://nbviewer.jupyter.org/github/Unidata/pyaos-ams-2021/blob/master/notebooks/visualization/matplotlib-intermediate.ipynb)\n", "\n", "\n", "Top" ] } ], "metadata": { "kernelspec": { "display_name": "Python [conda env:pyaos-ams-2021]", "language": "python", "name": "conda-env-pyaos-ams-2021-py" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.9.1" } }, "nbformat": 4, "nbformat_minor": 4 }