Recently I got a request to help with this question. I decided to create a post out of it because it is a nice example to show how to do something from start to finish. (Something that I have to do for my SWC training, but that is another story.)
First download the data from http://nsidc.org/data/NSIDC-0081. The binary file description says:
> One-byte flat scaled binary (preceded by a 300-byte header)
that means we can read the data with numpy's fromfile
after skipping the
header. We also need to re-size the matrix to the grid specifications:
> North: 304 columns x 448 rows
According to the documentation the sea ice concentration is scaled by 250, to make it simpler to plot let's just scaled it to 0-1. The final touch is to mask out the land values.
import numpy as np
import numpy.ma as ma
infile = './data/nt_20150326_f17_nrt_n.bin'
with open(infile, 'rb') as fr:
hdr = fr.read(300)
ice = np.fromfile(fr, dtype=np.uint8)
ice = ice.reshape(448, 304)
ice = ice / 250.
ice = ma.masked_greater(ice, 1.0)
The tricky part is to find the right projection to plot the data. Luckily, the text file that accompanies the data has everything we need. Including a proj4 string! (In case you are using Basemap or a future version of cartopy that is all you will need.)
!cat ./data/nt_20150326_f17_nrt_n.bin.txt
dx = dy = 25000
x = np.arange(-3850000, +3750000, +dx)
y = np.arange(+5850000, -5350000, -dy)
x.shape, y.shape, ice.shape
Finally the figure!
%matplotlib inline
import cartopy.crs as ccrs
import matplotlib.pyplot as plt
fig = plt.figure(figsize=(9, 9))
ax = plt.axes(projection=ccrs.NorthPolarStereo(central_longitude=0))
cs = ax.coastlines(resolution='110m', linewidth=0.5)
ax.gridlines()
ax.set_extent([-180, 180, 40, 90], crs=ccrs.PlateCarree())
kw = dict(central_latitude=90, central_longitude=-45, true_scale_latitude=70)
cs = ax.pcolormesh(x, y, ice, cmap=plt.cm.Blues,
transform=ccrs.Stereographic(**kw))
HTML(html)