Completed
Pull Request — master (#333)
by
unknown
01:34
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
32
# Function used to create the map subplots
33
def plot_background(ax):
34
    ax.set_extent([235., 290., 20., 55.])
35
    ax.coastlines('50m', edgecolor='black', linewidth=0.5)
36
    ax.add_feature(states_provinces, edgecolor='black', linewidth=0.5)
37
    ax.add_feature(country_borders, edgecolor='black', linewidth=0.5)
38
    return ax
39
40
41
###########################################
42
43
# Open the example netCDF data
44
ds = netCDF4.Dataset(get_test_data('gfs_output.nc', False))
45
print(ds)
46
47
###########################################
48
49
# Convert number of hours since the reference time into an actual date
50
time_vals = netCDF4.num2date(ds.variables['time'][:].squeeze(), ds.variables['time'].units)
51
52
###########################################
53
54
# Combine 1D latitude and longitudes into a 2D grid of locations
55
lon_2d, lat_2d = np.meshgrid(ds.variables['lon'][:], ds.variables['lat'][:])
56
57
###########################################
58
59
# Assign units
60
vort_500 = ds.variables['vort_500'][0] * units('1/s')  # To plot a e-5 s^-1
61
surface_temp = ds.variables['temp'][0] * units.kelvin
62
precip_water = ds.variables['precip_water'][0] * units.mm
63
winds_300 = ds.variables['winds_300'][0] * units('m/s')
64
65
###########################################
66
67
# Do unit conversions to what we wish to plot
68
vort_500 = vort_500 * 1e5
69
surface_temp = surface_temp.to('degF')
70
precip_water = precip_water.to('inches')
71
winds_300 = winds_300.to('knots')
72
73
###########################################
74
75
# Smooth the height data
76
heights_300 = ndimage.gaussian_filter(ds.variables['heights_300'][0], sigma=1.5, order=0)
77
heights_500 = ndimage.gaussian_filter(ds.variables['heights_500'][0], sigma=1.5, order=0)
78
79
###########################################
80
81
# Add state boundaries to plot
82
states_provinces = cfeature.NaturalEarthFeature(category='cultural',
83
                                                name='admin_1_states_provinces_lines',
84
                                                scale='50m', facecolor='none')
85
86
# Add country borders to plot
87
country_borders = cfeature.NaturalEarthFeature(category='cultural',
88
                                               name='admin_0_countries',
89
                                               scale='50m', facecolor='none')
90
91
crs = ccrs.LambertConformal(central_longitude=-100.0, central_latitude=45.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(r'$^o$F', 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