#sudo apt-get install libgeos-3.6.2
#sudo apt-get install libgeos-dev
#!pip install --upgrade matplotlib --ignore-installed
#!pip install https://github.com/matplotlib/basemap/archive/v1.2.2rel.zip
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
from mpl_toolkits.basemap import Basemap, addcyclic, shiftgrid
Attributes of .nc files: http://earthpy.org/04_work_with_different_data_formats.html#Open-netCDF-files
# https://rabernat.github.io/research_computing_2018/xarray-tips-and-tricks.html
url = 'http://www.esrl.noaa.gov/psd/thredds/dodsC/Datasets/ncep.reanalysis/surface/air.sig995.2018.nc'
from netCDF4 import Dataset as NetCDFFile
nc = NetCDFFile(url)
nc
# Extract data from NetCDF file (will take a minute)
lats = nc.variables['lat'][:]
lons = nc.variables['lon'][:]
time = nc.variables['time'][:]
air = nc.variables['air'][:] # shape is time, lat, lon
# Convert time values to datetime objects
import datetime as dt
dt_time = [dt.date(1, 1, 1) + dt.timedelta(hours=t) for t in time]
See http://matplotlib.org/basemap/users/mapsetup.html for other projections.
# Setup the map
m = Basemap(projection='moll', llcrnrlat=-90, urcrnrlat=90,\
llcrnrlon=0, urcrnrlon=360, resolution='c', lon_0=0)
m.drawcoastlines()
m.drawmapboundary()
# Take a random day in the year
time_idx = 237
cur_time = dt_time[time_idx]
print(cur_time)
# Make the plot continuous
air_cyclic, lons_cyclic = addcyclic(air[time_idx, :, :], lons)
# Shift the grid so lons go from -180 to 180 instead of 0 to 360.
air_cyclic, lons_cyclic = shiftgrid(180., air_cyclic, lons_cyclic, start=False)
# Create 2D lat/lon arrays for Basemap
lon2d, lat2d = np.meshgrid(lons_cyclic, lats)
# Transforms lat/lon into plotting coordinates for projection
x, y = m(lon2d, lat2d)
m.drawcoastlines()
m.drawmapboundary()
m.contourf(x, y, air_cyclic, 11, cmap=plt.cm.Spectral_r)
plt.title("Air temperature on %s" % cur_time)
plt.show()