Completed
Pull Request — master (#333)
by
unknown
02:04
created

plot_background()   A

Complexity

Conditions 1

Size

Total Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
c 1
b 0
f 0
dl 0
loc 6
rs 9.4285
1
# Copyright (c) 2008-2016 MetPy Developers.
2
# Distributed under the terms of the BSD 3-Clause License.
3
# SPDX-License-Identifier: BSD-3-Clause
4
"""
5
Four Panel Map
6
===============
7
8
By reading model output data from a netCDF file, we can create a four panel plot showing:
9
10
* 300 hPa heights and winds
11
* 500 hPa heights and absolute vorticity
12
* Surface temperatures
13
* Precipitable water
14
"""
15
16
###########################################
17
18
import cartopy.crs as ccrs
19
import cartopy.feature as cfeature
20
import matplotlib.gridspec as gridspec
21
import matplotlib.pyplot as plt
22
import netCDF4
23
import numpy as np
24
import scipy.ndimage as ndimage
25
26
from metpy.cbook import get_test_data
27
from metpy.units import units
28
29
###########################################
30
31
# Make state boundaries feature
32
states_provinces = cfeature.NaturalEarthFeature(category='cultural',
33
                                                name='admin_1_states_provinces_lines',
34
                                                scale='50m', facecolor='none')
35
36
# Make country borders feature
37
country_borders = cfeature.NaturalEarthFeature(category='cultural',
38
                                               name='admin_0_countries',
39
                                               scale='50m', facecolor='none')
40
41
crs = ccrs.LambertConformal(central_longitude=-100.0, central_latitude=45.0)
42
43
###########################################
44
45
46
# Function used to create the map subplots
47
def plot_background(ax):
48
    ax.set_extent([235., 290., 20., 55.])
49
    ax.coastlines('50m', edgecolor='black', linewidth=0.5)
50
    ax.add_feature(states_provinces, edgecolor='black', linewidth=0.5)
51
    ax.add_feature(country_borders, edgecolor='black', linewidth=0.5)
52
    return ax
53
54
55
###########################################
56
57
# Open the example netCDF data
58
ds = netCDF4.Dataset(get_test_data('gfs_output.nc', False))
59
print(ds)
60
61
###########################################
62
63
# Convert number of hours since the reference time into an actual date
64
time_vals = netCDF4.num2date(ds.variables['time'][:].squeeze(), ds.variables['time'].units)
65
66
###########################################
67
68
# Combine 1D latitude and longitudes into a 2D grid of locations
69
lon_2d, lat_2d = np.meshgrid(ds.variables['lon'][:], ds.variables['lat'][:])
70
71
###########################################
72
73
# Assign units
74
vort_500 = ds.variables['vort_500'][0] * units(ds.variables['vort_500'].units)
75
surface_temp = ds.variables['temp'][0] * units(ds.variables['temp'].units)
76
precip_water = ds.variables['precip_water'][0] * units(ds.variables['precip_water'].units)
77
winds_300 = ds.variables['winds_300'][0] * units(ds.variables['winds_300'].units)
78
79
###########################################
80
81
# Do unit conversions to what we wish to plot
82
vort_500 = vort_500 * 1e5
83
surface_temp = surface_temp.to('degF')
84
precip_water = precip_water.to('inches')
85
winds_300 = winds_300.to('knots')
86
87
###########################################
88
89
# Smooth the height data
90
heights_300 = ndimage.gaussian_filter(ds.variables['heights_300'][0], sigma=1.5, order=0)
91
heights_500 = ndimage.gaussian_filter(ds.variables['heights_500'][0], sigma=1.5, order=0)
92
93
###########################################
94
95
# Create the figure
96
fig = plt.figure(figsize=(20, 15))
97
gs = gridspec.GridSpec(5, 2, height_ratios=[1, .05, 1, .05, 0], bottom=.05, top=.95, wspace=.1)
98
99
100
# Upper left plot - 300-hPa winds and geopotential heights
101
ax1 = plt.subplot(gs[0, 0], projection=crs)
102
plot_background(ax1)
103
cf1 = ax1.contourf(lon_2d, lat_2d, winds_300, cmap='cool', transform=ccrs.PlateCarree())
104
c1 = ax1.contour(lon_2d, lat_2d, heights_300, colors='black', linewidth=2,
105
                 transform=ccrs.PlateCarree())
106
plt.clabel(c1, fontsize=10, inline=1, inline_spacing=1, fmt='%i', rightside_up=True)
107
108
ax2 = plt.subplot(gs[1, 0])
109
cb1 = plt.colorbar(cf1, cax=ax2, orientation='horizontal')
110
cb1.set_label('knots', size='x-large')
111
ax1.set_title('300-hPa Wind Speeds and Heights', fontsize=16)
112
113
# Upper right plot - 500mb absolute vorticity and geopotential heights
114
ax3 = plt.subplot(gs[0, 1], projection=crs)
115
plot_background(ax3)
116
cf2 = ax3.contourf(lon_2d, lat_2d, vort_500, cmap='BrBG', transform=ccrs.PlateCarree(),
117
                   zorder=0, norm=plt.Normalize(-32, 32), latlon=True)
118
c2 = ax3.contour(lon_2d, lat_2d, heights_500, colors='k', lw=2, transform=ccrs.PlateCarree())
119
plt.clabel(c2, fontsize=10, inline=1, inline_spacing=1, fmt='%i', rightside_up=True)
120
121
ax4 = plt.subplot(gs[1, 1])
122
cb2 = plt.colorbar(cf2, cax=ax4, orientation='horizontal')
123
cb2.set_label(r'$10^{-5}$ s$^{-1}$', size='x-large')
124
ax3.set_title('500-hPa Absolute Vorticity and Heights', fontsize=16)
125
126
# Lower left plot - surface temperatures
127
ax5 = plt.subplot(gs[2, 0], projection=crs)
128
plot_background(ax5)
129
cf3 = ax5.contourf(lon_2d, lat_2d, surface_temp, cmap='YlOrRd',
130
                   transform=ccrs.PlateCarree(), zorder=0)
131
132
ax6 = plt.subplot(gs[3, 0])
133
cb3 = plt.colorbar(cf3, cax=ax6, orientation='horizontal')
134
cb3.set_label(u'\N{DEGREE FAHRENHEIT}', size='x-large')
135
ax5.set_title('Surface Temperatures', fontsize=16)
136
137
# Lower right plot - precipitable water entire atmosphere
138
ax7 = plt.subplot(gs[2, 1], projection=crs)
139
plot_background(ax7)
140
cf4 = plt.contourf(lon_2d, lat_2d, precip_water, cmap='Greens',
141
                   transform=ccrs.PlateCarree(), zorder=0)
142
143
ax8 = plt.subplot(gs[3, 1])
144
cb4 = plt.colorbar(cf4, cax=ax8, orientation='horizontal')
145
cb4.set_label('in.', size='x-large')
146
ax7.set_title('Precipitable Water', fontsize=16)
147
148
fig.suptitle('{0:%d %B %Y %H:%MZ}'.format(time_vals), fontsize=24)
149
150
# Display the plot
151
plt.show()
152