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
|
|
|
=================== |
6
|
|
|
Point Interpolation |
7
|
|
|
=================== |
8
|
|
|
|
9
|
|
|
Compares different point interpolation approaches. |
10
|
|
|
""" |
11
|
|
|
import cartopy |
12
|
|
|
import cartopy.crs as ccrs |
13
|
|
|
from matplotlib.colors import BoundaryNorm |
14
|
|
|
import matplotlib.pyplot as plt |
15
|
|
|
import numpy as np |
16
|
|
|
|
17
|
|
|
from metpy.cbook import get_test_data |
18
|
|
|
from metpy.gridding.gridding_functions import (interpolate, remove_nan_observations, |
19
|
|
|
remove_repeat_coordinates) |
20
|
|
|
|
21
|
|
|
|
22
|
|
|
########################################### |
23
|
|
|
def basic_map(map_proj): |
24
|
|
|
"""Make our basic default map for plotting""" |
25
|
|
|
fig = plt.figure(figsize=(15, 10)) |
26
|
|
|
view = fig.add_axes([0, 0, 1, 1], projection=to_proj) |
27
|
|
|
view.set_extent([-120, -70, 20, 50]) |
28
|
|
|
view.add_feature(cartopy.feature.NaturalEarthFeature(category='cultural', |
29
|
|
|
name='admin_1_states_provinces_lakes', |
30
|
|
|
scale='50m', facecolor='none')) |
31
|
|
|
view.add_feature(cartopy.feature.OCEAN) |
32
|
|
|
view.add_feature(cartopy.feature.COASTLINE) |
33
|
|
|
view.add_feature(cartopy.feature.BORDERS, linestyle=':') |
34
|
|
|
return view |
35
|
|
|
|
36
|
|
|
|
37
|
|
View Code Duplication |
def station_test_data(variable_names, proj_from=None, proj_to=None): |
|
|
|
|
38
|
|
|
|
39
|
|
|
f = get_test_data('station_data.txt') |
40
|
|
|
|
41
|
|
|
all_data = np.loadtxt(f, skiprows=1, delimiter=',', |
42
|
|
|
usecols=(1, 2, 3, 4, 5, 6, 7, 17, 18, 19), |
43
|
|
|
dtype=np.dtype([('stid', '3S'), ('lat', 'f'), ('lon', 'f'), |
44
|
|
|
('slp', 'f'), ('air_temperature', 'f'), |
45
|
|
|
('cloud_fraction', 'f'), ('dewpoint', 'f'), |
46
|
|
|
('weather', '16S'), |
47
|
|
|
('wind_dir', 'f'), ('wind_speed', 'f')])) |
48
|
|
|
|
49
|
|
|
all_stids = [s.decode('ascii') for s in all_data['stid']] |
50
|
|
|
|
51
|
|
|
data = np.concatenate([all_data[all_stids.index(site)].reshape(1, ) for site in all_stids]) |
52
|
|
|
|
53
|
|
|
value = data[variable_names] |
54
|
|
|
lon = data['lon'] |
55
|
|
|
lat = data['lat'] |
56
|
|
|
|
57
|
|
|
if proj_from is not None and proj_to is not None: |
58
|
|
|
|
59
|
|
|
try: |
60
|
|
|
|
61
|
|
|
proj_points = proj_to.transform_points(proj_from, lon, lat) |
62
|
|
|
return proj_points[:, 0], proj_points[:, 1], value |
63
|
|
|
|
64
|
|
|
except Exception as e: |
65
|
|
|
|
66
|
|
|
print(e) |
67
|
|
|
return None |
68
|
|
|
|
69
|
|
|
return lon, lat, value |
70
|
|
|
|
71
|
|
|
|
72
|
|
|
from_proj = ccrs.Geodetic() |
73
|
|
|
to_proj = ccrs.AlbersEqualArea(central_longitude=-97.0000, central_latitude=38.0000) |
74
|
|
|
|
75
|
|
|
levels = list(range(-20, 20, 1)) |
76
|
|
|
cmap = plt.get_cmap('magma') |
77
|
|
|
norm = BoundaryNorm(levels, ncolors=cmap.N, clip=True) |
78
|
|
|
|
79
|
|
|
x, y, temp = station_test_data('air_temperature', from_proj, to_proj) |
80
|
|
|
|
81
|
|
|
x, y, temp = remove_nan_observations(x, y, temp) |
82
|
|
|
x, y, temp = remove_repeat_coordinates(x, y, temp) |
83
|
|
|
|
84
|
|
|
########################################### |
85
|
|
|
# ------------------------ |
86
|
|
|
# Scipy.interpolate linear |
87
|
|
|
# ------------------------ |
88
|
|
|
gx, gy, img = interpolate(x, y, temp, interp_type='linear', hres=75000) |
89
|
|
|
img = np.ma.masked_where(np.isnan(img), img) |
90
|
|
|
view = basic_map(to_proj) |
91
|
|
|
mmb = view.pcolormesh(gx, gy, img, cmap=cmap, norm=norm) |
92
|
|
|
plt.colorbar(mmb, shrink=.4, pad=0, boundaries=levels) |
93
|
|
|
|
94
|
|
|
########################################### |
95
|
|
|
# ----------------------------------------------------- |
96
|
|
|
# Natural neighbor interpolation (MetPy implementation) |
97
|
|
|
# ----------------------------------------------------- |
98
|
|
|
# `Reference <https://github.com/Unidata/MetPy/files/138653/cwp-657.pdf>`_ |
99
|
|
|
gx, gy, img = interpolate(x, y, temp, interp_type='natural_neighbor', hres=75000) |
100
|
|
|
img = np.ma.masked_where(np.isnan(img), img) |
101
|
|
|
view = basic_map(to_proj) |
102
|
|
|
mmb = view.pcolormesh(gx, gy, img, cmap=cmap, norm=norm) |
103
|
|
|
plt.colorbar(mmb, shrink=.4, pad=0, boundaries=levels) |
104
|
|
|
|
105
|
|
|
########################################### |
106
|
|
|
# ---------------------- |
107
|
|
|
# Cressman interpolation |
108
|
|
|
# ---------------------- |
109
|
|
|
# search_radius = 100 km |
110
|
|
|
# |
111
|
|
|
# grid resolution = 25 km |
112
|
|
|
# |
113
|
|
|
# min_neighbors = 1 |
114
|
|
|
gx, gy, img = interpolate(x, y, temp, interp_type='cressman', minimum_neighbors=1, hres=75000, |
115
|
|
|
search_radius=100000) |
116
|
|
|
img = np.ma.masked_where(np.isnan(img), img) |
117
|
|
|
view = basic_map(to_proj) |
118
|
|
|
mmb = view.pcolormesh(gx, gy, img, cmap=cmap, norm=norm) |
119
|
|
|
plt.colorbar(mmb, shrink=.4, pad=0, boundaries=levels) |
120
|
|
|
|
121
|
|
|
########################################### |
122
|
|
|
# -------------------- |
123
|
|
|
# Barnes Interpolation |
124
|
|
|
# -------------------- |
125
|
|
|
# search_radius = 100km |
126
|
|
|
# |
127
|
|
|
# min_neighbors = 3 |
128
|
|
|
gx, gy, img1 = interpolate(x, y, temp, interp_type='barnes', hres=75000, search_radius=100000) |
129
|
|
|
img1 = np.ma.masked_where(np.isnan(img1), img1) |
130
|
|
|
view = basic_map(to_proj) |
131
|
|
|
mmb = view.pcolormesh(gx, gy, img1, cmap=cmap, norm=norm) |
132
|
|
|
plt.colorbar(mmb, shrink=.4, pad=0, boundaries=levels) |
133
|
|
|
|
134
|
|
|
########################################### |
135
|
|
|
# ------------------------------------ |
136
|
|
|
# Radial basis function interpolation |
137
|
|
|
# ------------------------------------ |
138
|
|
|
# linear |
139
|
|
|
gx, gy, img = interpolate(x, y, temp, interp_type='rbf', hres=75000, rbf_func='linear', |
140
|
|
|
rbf_smooth=0) |
141
|
|
|
img = np.ma.masked_where(np.isnan(img), img) |
142
|
|
|
view = basic_map(to_proj) |
143
|
|
|
mmb = view.pcolormesh(gx, gy, img, cmap=cmap, norm=norm) |
144
|
|
|
plt.colorbar(mmb, shrink=.4, pad=0, boundaries=levels) |
145
|
|
|
|
146
|
|
|
plt.show() |
147
|
|
|
|