axes
objects and set various axes attributes.mat
FilesThe scipy.io module contains methods for inspecting MATLAB formatted data (.mat
) files, reading them into NumPy data structures, and saving NumPy arrays as .mat
files.
import numpy as np import matplotlib.pyplot as plt import scipy.io as sio %matplotlib inline
Let's explore the Pacific Northwest coastline polygons file that Rich created from BC provincial and WA state data. Listing the variables in the file:
sio.whosmat('PNW.mat')
[('k', (13914, 1), 'double'), ('Area', (1, 13913), 'double'), ('ncst', (1470658, 2), 'double'), ('data_source', (16,), 'char')]
and loading the file into a Python varible:
pnw = sio.loadmat('PNW.mat')
Now let's see what the data looks like.
Caution Doing this can return a lot of output if the file is not as nicely structured as this one.
pnw
{'Area': array([[ 3.16521920e+01, 3.95526325e+00, 1.12423973e+01, ..., 4.44114418e-09, 4.03697403e-09, 6.50091288e-09]]), '__globals__': [], '__header__': 'MATLAB 5.0 MAT-file, Platform: GLNXA64, Created on: Tue Sep 23 21:31:54 2014', '__version__': '1.0', 'data_source': array([u'The Pacific North-West coastline in PNW.mat was created from ', u'two sources: ', u' a) BC Freshwater Atlas Coastline (FWCSTLNSSP) available as an ', u' Arcview shapefile from GeoBC, and ', u' b) WA Marine Shorelines (shore_arc), available as a shapefile ', u' on a lambert conformal projection from WA State Dept. of ', u' Ecology. ', u' ', u' The WA coastline was converted to lat/long using m_map and ', u' all island arcs were then joined into continous oriented ', u' polygons, and the coastline itself was converted into a ', u' polygon by the addition of inland corners. ', u' ', u' The result is (supposedly) on the NAD83 horizontal datum ', u' - Rich Pawlowicz (rich@eos.ubc.ca) ', u' July/2013 '], dtype='<U63'), 'k': array([[ 1], [ 396666], [ 639200], ..., [1470648], [1470653], [1470658]], dtype=int32), 'ncst': array([[ nan, nan], [-127.63646203, 52.0126776 ], [-120. , 52.0126 ], ..., [-127.59785952, 50.09807875], [-127.59789159, 50.09793491], [ nan, nan]])}
The ncst
variable is a 2-column collection of NaN-separated line segments that make polygons for the BC/WA coast. The line segment end points are given in longitude/latitude pairs that we can easily extract into a pair of NumPy arrays:
lats = pnw['ncst'][:, 1] lons = pnw['ncst'][:, 0]
and plot:
plt.plot(lons, lats) plt.show()
To really take control of plots we need to start working with axes
objects. Here we will:
fig, ax = plt.subplots(1, 1, figsize=(10, 10)) ax.plot(lons, lats, color='black', rasterized=True) ax.set_axis_bgcolor('lightgrey') ax.set_xlim([-126.4, -121.3]) ax.set_ylim([46.8, 51.1]) ax.set_xlabel('Longitude [degrees east]') ax.set_ylabel('Latitude [degrees north]') ax.set_title('Salish Sea Coastline', fontsize=18) plt.show()
Now, let's add some annotations:
fig, ax = plt.subplots(1, 1, figsize=(10, 10)) ax.plot(lons, lats, color='black', rasterized=True) ax.set_axis_bgcolor('lightgrey') ax.set_xlim([-126.4, -121.3]) ax.set_ylim([46.8, 51.1]) ax.set_xlabel('Longitude [degrees east]') ax.set_ylabel('Latitude [degrees north]') ax.set_title('Salish Sea Coastline', fontsize=18) # Annotate geography ax.text(-126, 48,'Pacific Ocean', fontsize=16) ax.text(-124.1, 47.6,'Washington\nState', fontsize=16) ax.text(-122.3, 47.6,'Puget Sound', fontsize=12) ax.text(-125.6, 49.3,'Vancouver\nIsland', fontsize=14) ax.text(-123, 50,'British Columbia', fontsize=16) ax.text(-124.6, 48.4,'Strait of Juan de Fuca', fontsize=11, rotation=-13) ax.text(-123.9, 49.2,'Strait of\n Georgia', fontsize=11, rotation=-2) plt.show()
Mark some of the important cities and annotate them with arrows and labels:
fig, ax = plt.subplots(1, 1, figsize=(10, 10)) ax.plot(lons, lats, color='black', rasterized=True) ax.set_axis_bgcolor('lightgrey') ax.set_xlim([-126.4, -121.3]) ax.set_ylim([46.8, 51.1]) ax.set_xlabel('Longitude [degrees east]') ax.set_ylabel('Latitude [degrees north]') ax.set_title('Salish Sea Coastline', fontsize=18) # Annotate geography ax.text(-126, 48,'Pacific Ocean', fontsize=16) ax.text(-124.1, 47.6,'Washington\nState', fontsize=16) ax.text(-122.3, 47.6,'Puget Sound', fontsize=12) ax.text(-125.6, 49.3,'Vancouver\nIsland', fontsize=14) ax.text(-123, 50,'British Columbia', fontsize=16) ax.text(-124.6, 48.4,'Strait of Juan de Fuca', fontsize=11, rotation=-13) ax.text(-123.9, 49.2,'Strait of\n Georgia', fontsize=11, rotation=-2) # Mark cities cities = ( ('Victoria', -123.3657, 48.4222, -80, 20), ('Vancouver', -123.1, 49.25, 60, -20), ('Campbell River', -125.2475, 50.0244, -70, -30), ) arrow_properties = { 'arrowstyle': '->', 'connectionstyle': 'arc3, rad=0', } for name, lon, lat, textx, texty in cities: ax.plot(lon, lat, marker='*', color='red', markersize=15) ax.annotate( name, xy=(lon, lat), xytext=(textx, texty), textcoords='offset points', fontsize=11, arrowprops=arrow_properties, ) plt.show()
We can save our plot to an image file with the savefig()
method of the figure object. Many image formats are supported, but if you can't decide, PNG is a good choice.
fig.savefig('SalishSeaGeography.png')
The coastline data above is strictly 2-dimensional. If we also have depth and/or altitude data we show that dimension via colourmaps and contour lines.
Jody Klymak at UVic has created a .mat
file of the southern Vancouver Island coastal shelf region from the Cascadia bathymetry/topography dataset.
sio.whosmat('SouthVIgrid.mat')
[('SouthVIgrid', (1, 1), 'struct')]
svi = sio.loadmat('SouthVIgrid.mat')
The file structure is a little more compicated than Rich's PNW file, so we'll just use some code that Jody provided to extract the lats, lons, and elevations.
topo_struct = svi['SouthVIgrid'] topo = topo_struct[0,0] xmask = np.where( np.logical_and( np.squeeze(topo['lon'] > -126.7), np.squeeze(topo['lon'] < -122)))[0] ymask = np.where( np.logical_and( np.squeeze(topo['lat'] > 46), np.squeeze(topo['lat'] < 50)))[0]
x = np.squeeze(topo['lon'])[xmask] y = np.squeeze(topo['lat'])[ymask] z = topo['depth'][ymask, :][:, xmask]