General Format#
This page introduces the general visualization template for building multi-panel figures in Python using consistent formatting and automated output naming.
🧰 Goal#
This template provides a standard way to:
Auto-name figure outputs to match the notebook or script
Create a consistent 2×3 subplot layout
Style each panel with
GeoCATutilitiesSave visualizations with professional layout and naming conventions
🧱 1. Load Required Packages#
We organize imports into functional groups for clarity:
# --- Packages ---
## General Packages
import pandas as pd
import xarray as xr
import numpy as np
import os
import ipynbname
import cftime
## GeoCAT
import geocat.comp as gccomp
import geocat.viz as gv
import geocat.viz.util as gvutil
## Regridding and geopandas if required
#import xesmf as xe
#import geopandas as gpd
## Visualization
import cmaps
import cartopy.crs as ccrs
import cartopy.feature as cfeature
import shapely.geometry as sgeom
## MatPlotLib
import matplotlib.pyplot as plt
import matplotlib.ticker as mticker
import matplotlib.patches as mpatches
import matplotlib.dates as mdates
import matplotlib.patheffects as pe
from matplotlib.colors import ListedColormap, BoundaryNorm
from matplotlib.ticker import MultipleLocator
## Unique Plots
import matplotlib.gridspec as gridspec
# NCL Fonts
plt.rcParams["font.family"] = "DejaVu Sans"
plt.rcParams["font.size"] = 12
Required Python Packages#
PyCLM101 relies on a core set of Python packages commonly used in climate data analysis, visualization, and geospatial processing.
Packages are grouped by functionality to keep workflows readable and reproducible.
General Scientific and I/O Packages#
pandas(pd)
Tabular data analysis and time-series handling, particularly useful for station data, indices, and summary tables.xarray(xr)
Core package for working with multi-dimensional climate data (NetCDF, GRIB). Enables labeled dimensions, CF-compliant metadata handling, and seamless integration with Dask.numpy(np)
Fundamental numerical array operations used throughout all analysis steps.os
File and directory management for reproducible workflows.ipynbname
Retrieves the filename of the active Jupyter Notebook. Useful for automated figure naming and tracking analysis provenance.cftime
Provides support for non-standard, CF-compliant calendars (e.g.,360_day,noleap) commonly used in climate model output. Essential when working with model time coordinates inxarray.
GeoCAT (NCL-to-Python Transition)#
geocat.comp(gccomp)
Climate analysis utilities designed to support workflows familiar to NCL users, including interpolation, meteorological diagnostics, and EOF-related helper functions.geocat.viz(gv,gvutil)
Visualization utilities for producing consistent, publication-quality figures. These functions simplify common tasks such as colorbar placement, labeling, and multi-panel map layouts.
GeoCAT plays a central role in PyCLM101 by easing the transition from NCL to Python-based analysis.
Regridding and Vector Geospatial Tools#
xesmf(xe)
A flexible regridding package supporting conservative, bilinear, and nearest-neighbor methods. Commonly used to remap data between model grids and observational products.
(Note: ESMF/ESMPy is required in most environments.)geopandas(gpd)
High-level tools for handling vector geospatial data (shapefiles, GeoJSON). Useful for spatial masking, administrative boundaries, and regional analysis.shapely.geometry(sgeom)
Geometry primitives and spatial operations such as polygon creation, buffering, and intersections. Often used to define custom analysis domains.
Visualization and Mapping#
matplotlib(plt,ticker,patches,dates,patheffects)
Core plotting library used for all figures in PyCLM101, including time series, spatial maps, and multi-panel layouts.cartopy(ccrs,cfeature)
Cartographic plotting library for map projections and geospatial features such as coastlines, borders, and state outlines.cmaps
Provides access to climate-oriented colormap collections, often used to reproduce NCL-style color schemes.
For perceptually uniform alternatives, users may also considercmoceanorcmcrameri.matplotlib.gridspec
Enables fine control of multi-panel figure layouts, which is frequently used in climate diagnostics.
Global Plot Settings#
The following matplotlib.rcParams settings define global defaults for all figures created within a notebook session:
plt.rcParams["font.family"] = "DejaVu Sans"
plt.rcParams["font.size"] = 12
📁 2. Auto-Naming Output Figure Files#
To improve reproducibility and reduce manual file-naming errors, PyCLM101 adopts an automatic approach for generating output figure filenames.
This approach is particularly useful when figures are regenerated multiple times or shared across scripts and notebooks.
The helper function below detects the execution environment and extracts the base filename accordingly:
Python script (
.py): Uses the script name.Jupyter Notebook (
.ipynb): Uses the notebook filename viaipynbname.Fallback: Uses a user-defined default name if neither is available.
def get_filename(default="figure"):
"""Return the base filename of the current script or notebook."""
# Case 1: running from a .py file
if "__file__" in globals():
return os.path.splitext(os.path.basename(__file__))[0]
# Case 2: running inside Jupyter Notebook
try:
import ipynbname
nb_path = ipynbname.path()
return os.path.splitext(os.path.basename(str(nb_path)))[0]
except Exception:
# Fallback
return default
# --- Example usage ---
base = get_filename("template_eof_US")
fnFIG = f"{base}.png"
fnEPS = f"{base}.eps"
print(f"Figure filename: {fnFIG}")
With this setup, figures are saved using the same base name as the script or notebook, for example:
eof_analysis.ipynb→eof_analysis.pngplot_climatology.py→plot_climatology.png
This practice ensures consistent figure naming, simplifies batch processing, and maintains a clear link between figures and their source code.
🖼 3. Create a 2×3 Multi-Panel Layout#
Define your plot layout using plt.subplots() with nrows=2, ncols=3, which creates a grid of six subplots.
fig, axes = plt.subplots(nrows=2, ncols=3, figsize=(7, 12))
col = cmaps.amwg
Each panel can be accessed using an index like this:
ip = 0
axes[ip].plot(dat.year, series)
Use gvutil.set_titles_and_labels() to apply consistent title formatting, label size, and axis annotation:
gvutil.set_titles_and_labels(axes[ip],
maintitle="",
lefttitle="(a)",
righttitle="",
ylabel="Some Variable",
xlabel="Year",
maintitlefontsize=14,
lefttitlefontsize=12,
labelfontsize=10)
🔁 Repeat for each panel#
Update the index (ip = 1, ip = 2, …) and change data, titles, or labels as needed for each subplot.
🎨 Tips for Styling#
Use consistent colormaps from
cmaps.amwgto match climate science standardsAdd horizontal lines (
axhline(0)) for referenceSet axis limits and ticks using
gvutil.set_axes_limits_and_ticks()orMultipleLocator
💾 4. Save and Show the Output#
Save the figure using the generated filename:
plt.tight_layout()
plt.savefig(fnFIG, dpi=300, bbox_inches="tight")
plt.show()
tight_layout()prevents label and title clippingdpi=300ensures publication-quality resolutionbbox_inches="tight"trims whitespace around the plot
✅ Summary#
This general template streamlines plotting by:
Automating repetitive tasks
Enforcing visual consistency
Saving high-quality figures automatically
Adapt this template for EOF maps, correlation fields, seasonal plots, and other visualizations.