Plotting Examples

import xarray as xr
import matplotlib.pyplot as plt

import cartopy.crs as ccrs
import cartopy.feature as cfeature
url = 'http://kage.ldeo.columbia.edu:81/SOURCES/.LOCAL/.sst.mon.mean.nc/.sst/time/AVERAGE/dods'
ds = xr.open_dataset(url).sst

Set a plot size and pick a cartopy projection

fig = plt.figure(figsize=(9, 5))

# Pick a [cartopy projection](https://scitools.org.uk/cartopy/docs/latest/crs/projections.html)
ax = plt.axes(projection=ccrs.PlateCarree(central_longitude=180));

Plot coastlines and then pick a transform.

ax.coastlines()
ds.plot.contour(ax=ax, transform=ccrs.PlateCarree(),levels=30)

Add feature, if desired: (typing <Tab> after cfeature. will list possible completions)

ax.add_feature(cfeature.BORDERS)
import numpy as np
import xarray as xr
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
import cartopy.feature as cfeature
url = 'http://kage.ldeo.columbia.edu:81/SOURCES/.LOCAL/.sst.mon.mean.nc/.sst/time/AVERAGE/dods'
ds = xr.open_dataset(url).sel(lat=slice(50,-50)).sst
fig = plt.figure(figsize=(8,5))
ax = plt.axes(projection=ccrs.PlateCarree(central_longitude=180))
ax.set_extent([100, 290, -50, 50], crs=ccrs.PlateCarree())

# Put a background image on for nice sea rendering.
ax.stock_img()
CS = ds.plot.contour(ax=ax, transform=ccrs.PlateCarree(),colors='k',vmin=10,vmax=30,levels=11)
# Add labels on contours
ax.clabel(CS, inline=1, fontsize=8, fmt='%1.0f')

# Create a feature for States/Admin 1 regions at 1:50m from Natural Earth
states_provinces = cfeature.NaturalEarthFeature(
    category='cultural',
    name='admin_1_states_provinces_lines',
    scale='50m',
    facecolor='none')

ax.add_feature(cfeature.COASTLINE,zorder=3)
ax.add_feature(cfeature.BORDERS, edgecolor='gray')
ax.add_feature(states_provinces, edgecolor='gray')

# Add longitude, latitude labels
gl = ax.gridlines(draw_labels=True, alpha=0.0, xlocs=np.arange(-160,181,20))
gl.top_labels = False

The built-in xarray plotting allows for multiple plots:

ds = xr.open_dataset('http://kage.ldeo.columbia.edu:81/SOURCES/.LOCAL/.sst.mon.mean.nc/.sst/dods')
ds_mon_anom = ds.groupby('time.month').mean() - ds.mean('time')
ds_mon_anom.sst.plot(x='lon',y='lat',col='month',col_wrap=4,add_colorbar=0);

But much more control is possible when using matplotlib directly, see subplots.

The keyword arguments xincrease and yincrease control the axis direction.

import xarray as xr
url = 'http://kage.ldeo.columbia.edu:81/SOURCES/.LOCAL/.ORAs5_thetao-clim.nc/.thetao/dods'
ds = xr.open_dataset(url,decode_times=False).sel(deptht=slice(0,300),lat=slice(-30,30),lon=slice(150,250)).mean('time')

ds.thetao.sel(lat=slice(-2,2)).mean('lat').plot.contourf(vmin=10,vmax=30,levels=11,yincrease=False)

Plotting DataArrays: For examples of all of the following, see xarray plotting

There are also other plotting methods, such as ds.plot.violin, ds.plot.bivariate, ds.plot.table, etc.

IRIDL has started using hvplot, which is an interactive plotting tool. We have installed it on carney, and find it cute, but somewhat frustrating.

%ingrid
 SOURCES .DASILVA .SMD94 .anomalies .sst correlationcolorscale
  DATA -2 2 RANGE
  X -100 20 RANGE
  Y 0 90 RANGE
  /color_smoothing null def
 SOURCES .DASILVA .SMD94 .anomalies .slp
   X -100 20 RANGE
   Y 0 90 RANGE
   DATA 5 STEP
   X Y fig: colors contours land :fig

Try to match this ingrid figure as closely as possible in python …

#python
import xarray as xr
import pandas as pd
import numpy as np

import matplotlib.pyplot as plt
from matplotlib import colors

import cartopy.crs as ccrs
import cartopy.feature as cfeature
from cartopy.mpl.ticker import LongitudeFormatter, LatitudeFormatter
# Get the Dataset
url = 'http://kage.ldeo.columbia.edu:81/SOURCES/.DASILVA/.SMD94/.anomalies/.sst/dods'
url2 = 'http://kage.ldeo.columbia.edu:81/SOURCES/.DASILVA/.SMD94/.anomalies/.slp/dods'

ds = xr.open_dataset(url,decode_times=False)
ds['slp'] = xr.open_dataset(url2,decode_times=False).slp

# Fix the grids
ds['T'] = pd.date_range('1945-01',periods=len(ds.T), freq='MS').shift(15,freq='D')
ds.coords['X'] = (ds.coords['X'] + 180) % 360 - 180
ds = ds.sortby(ds.X)

# Restrict the domain
dss = ds.sel(X=slice(-100,20),Y=slice(-10,90)).isel(T=0)
  
## Now make the figure
 
cmap_data = [(0, 'navy'),(0.1, 'blue'),(0.2, 'DeepSkyBlue'),(0.3, 'aquamarine'),(0.4,'PaleGreen'),(0.45,'moccasin'),
             (0.55,'moccasin'),(.6,'yellow'),(.7,'DarkOrange'),(.8,'red'),(1.0,'DarkRed')]
cmap = colors.LinearSegmentedColormap.from_list('correlationcolorscale', cmap_data)
plt.register_cmap('correlationcolorscale', cmap)

fig = plt.figure(figsize=(8,8))

ax = plt.axes(projection=ccrs.PlateCarree(central_longitude=0))
ax.set_extent([-100, 20, 0, 90], crs=ccrs.PlateCarree())

cb = dss.sst.plot.contourf(ax=ax, transform=ccrs.PlateCarree(), vmin=-2, vmax=2, levels=41, cmap='correlationcolorscale',
                           add_colorbar=False,rasterized=True)
CS = dss.slp.plot.contour(ax=ax, colors = 'black', transform=ccrs.PlateCarree(), vmin=-20, vmax=20, levels=9)
CS.collections[4].set_linewidth(3) # make the zero line wider
ax.clabel(CS, inline=1, fontsize=8, fmt='%1.0f')

ax.add_feature(cfeature.LAND,facecolor='k')

cbar = plt.colorbar(cb, extend = 'min', shrink=1.0, pad=.10, label=r'SSTA ($\degree C$)', orientation='horizontal')

xticks = np.arange(-80, 0.1, 20)
yticks = np.arange(20, 80.1, 20)
ax.set_xticks(xticks, crs=ccrs.PlateCarree())
ax.set_yticks(yticks, crs=ccrs.PlateCarree())
ax.xaxis.set_major_formatter(LongitudeFormatter(zero_direction_label=True))
ax.yaxis.set_major_formatter(LatitudeFormatter())

ax.set_xlabel('longitude')
ax.set_ylabel('latitude')
import xarray as xr
import numpy as np
import os

from matplotlib.ticker import (MultipleLocator, AutoMinorLocator)
import matplotlib.patches as mpatches
import matplotlib.pyplot as plt
from matplotlib import colors as colors

import cartopy.crs as ccrs
import cartopy.feature as cfeature
from cartopy.mpl.ticker import LongitudeFormatter, LatitudeFormatter

# Define a new colormap for plotting SST anomalies
cmap_data = [(0, 'navy'),(0.1, 'blue'),(0.2,'DeepSkyBlue'),
             (0.3,'aquamarine'),(0.4,'PaleGreen'),(0.45,'moccasin'),
             (0.55,'moccasin'),(.6,'yellow'),(.7,'DarkOrange'),
             (.8,'red'),(1.0,'DarkRed')]
cmap = colors.LinearSegmentedColormap.from_list('correlationcolorscale', cmap_data)
plt.register_cmap('correlationcolorscale', cmap)

# Get some sst data for plotting
url = 'http://kage.ldeo.columbia.edu:81/SOURCES/.LOCAL/.sst.mon.mean.nc/.sst/dods'
ds = xr.open_dataset(url)
ds = ds.sel(time=slice('1979-01','2021-07'))
  
# Divide the map at 20E to avoid splitting Atlantic or Pacific
lon_start = 20
ds.coords['lon'] = (ds.coords['lon'] - lon_start) % 360 + lon_start ; ds = ds.sortby('lon')
ds_anom = ds.groupby('time.month').apply(lambda x: x - x.mean('time'))

# Start Figure
fig = plt.figure(figsize=(9,2.5))
ax = plt.axes(projection=ccrs.PlateCarree(central_longitude=200))
crs = ccrs.PlateCarree()
ax.set_extent([-20, 380, -50,  50], crs=crs)

# Draw color-filled contours
cs = ds_anom.sst[-1].plot.contourf(ax=ax, transform=ccrs.PlateCarree(),vmin=-2, vmax=2, levels=41, cmap='correlationcolorscale', add_colorbar=False)  
  
# Add coasts and country borders  
ax.add_feature(cfeature.COASTLINE, linewidth=1.0)
ax.add_feature(cfeature.BORDERS, linewidth=0.5)

# Use the figsize to determine the aspect ratio, not cartopy
ax.set_aspect('auto')

# Label x-axis and make tick labels
ax.xaxis.set_label_text('Longitude',fontsize=8)
ax.set_xticks(np.arange(60,380,40), crs=ccrs.PlateCarree())
ax.xaxis.set_major_formatter(LongitudeFormatter())
ax.xaxis.set_minor_locator(MultipleLocator(10))

# Label y-axis and make tick labels
ax.yaxis.set_label_text('Latitude',fontsize=8)
plt.yticks(np.arange(-40,41,20), rotation=90, va='center')
ax.yaxis.set_major_formatter(LatitudeFormatter())
ax.yaxis.set_minor_locator(MultipleLocator(10))

# Make tick marks
ax.tick_params(which='major', width=1.00, length=5, labelsize=7)
ax.tick_params(which='minor', width=0.75, length=2.5)

# Add Nino3.4 box
rect = mpatches.Rectangle(xy=[190, -5], width=50, height=10, fill=False, transform=crs, linestyle='--')
ax.add_patch(rect)
ax.annotate('NINO3.4', xy=(215, 8), xycoords=crs._as_mpl_transform(ax), ha='center', va='center', fontsize=8)

cbar = plt.colorbar(cs, extendrect = True, label=r'SSTA [$\degree C$]')
  
plt.title('SST anomalies, June 2021')
plt.tight_layout();




Basic Examples : Advanced Examples : Plotting : Troubleshooting : Notebooks

 

XARRAY LINKS: User Guide : How Do I...?