Hydrometeorclassification - PPI#
The hydrometeorclassification code is based on the paper by Zrnic et.al 2001 utilizing 2D trapezoidal membership functions based on the paper by Straka et. al 2000 adapted by Evaristo et. al 2013 for X-Band.
PPI Stratiform (2014-10-07 02:45)
PPI Convective (2013-07-01 15:40)
import datetime as dt
import matplotlib.pyplot as plt
import numpy as np
import wradlib as wrl
import xarray as xr
Utility Functions#
import radarpolarimetry as rp
Precipitation Types#
pr_types = dict(wrl.classify.pr_types.values())
for k, v in enumerate(pr_types.items()):
print(f"{k:02} {' - '.join(v)}")
00 LR - Light Rain
01 MR - Moderate Rain
02 HR - Heavy Rain
03 LD - Large Drops
04 HL - Hail
05 RH - Rain/Hail
06 GH - Graupel/Hail
07 DS - Dry Snow
08 WS - Wet Snow
09 HC - H Crystals
10 VC - V Crystals
11 NP - No Precip
Load 2D Membership Functions#
filename = "/radar/wradlib-data/misc/msf_xband_v1.nc"
with rp.rpol_data.open(filename) as f:
filename = f.name
msf = xr.open_dataset(filename)
display(msf)
<xarray.Dataset> Size: 97kB
Dimensions: (hmc: 11, idp: 55, trapezoid: 4)
Coordinates:
* hmc (hmc) <U2 88B 'LR' 'MR' 'HR' 'LD' 'HL' ... 'GH' 'DS' 'WS' 'HC' 'VC'
* idp (idp) float64 440B -10.0 -8.0 -6.0 -4.0 ... 92.0 94.0 96.0 98.0
Dimensions without coordinates: trapezoid
Data variables:
ZH (hmc, idp, trapezoid) float64 19kB ...
ZDR (hmc, idp, trapezoid) float64 19kB ...
RHO (hmc, idp, trapezoid) float64 19kB ...
KDP (hmc, idp, trapezoid) float64 19kB ...
TEMP (hmc, idp, trapezoid) float64 19kB ...
Attributes:
version: 1
title: 2D Membershipfunctions Hydrometeorclassification for XBand
institution: Institute of Geosciences, Meteorology Section, University o...
history: created by Raquel Evaristo, adapted to netCDF by Kai Mühlbauer
comment: created with wradlibStratiform#
filename = "/radar/rp-data/workflow/tmp_20141007T0245_20141007T0250_workflow.nc"
with rp.rpol_data.open(filename) as f:
filename = f.name
sweep_s = xr.open_dataset(filename)
display(sweep_s)
<xarray.Dataset> Size: 138MB
Dimensions: (azimuth: 360, range: 1000)
Coordinates: (12/22)
* azimuth (azimuth) float64 3kB 0.5 1.5 2.5 ... 357.5 358.5 359.5
elevation (azimuth) float64 3kB ...
time (azimuth) datetime64[ns] 3kB ...
* range (range) float32 4kB 50.0 150.0 ... 9.985e+04 9.995e+04
x (azimuth, range) float64 3MB ...
y (azimuth, range) float64 3MB ...
... ...
crs_wkt int64 8B ...
band int64 8B ...
spatial_ref int64 8B ...
stdev float64 8B ...
NOISE_LEVEL float64 8B ...
alpha float64 8B ...
Data variables: (12/55)
KDP (azimuth, range) float32 1MB ...
PHIDP (azimuth, range) float32 1MB ...
DBZH (azimuth, range) float32 1MB ...
DBZV (azimuth, range) float32 1MB ...
RHOHV (azimuth, range) float32 1MB ...
DBTH (azimuth, range) float32 1MB ...
... ...
AH (azimuth, range) float64 3MB ...
KDP_AH (azimuth, range) float64 3MB ...
PHIDP_CORR5 (azimuth, range) float64 3MB ...
DBTH_CORR5 (azimuth, range) float64 3MB ...
DBZH_CORR5 (azimuth, range) float64 3MB ...
ZDR_CORR5 (azimuth, range) float64 3MB ...Convective#
filename = "/radar/rp-data/workflow/tmp_20130701T1540_20130701T1545_workflow.nc"
with rp.rpol_data.open(filename) as f:
filename = f.name
sweep_c = xr.open_dataset(filename)
display(sweep_c)
<xarray.Dataset> Size: 138MB
Dimensions: (azimuth: 360, range: 1000)
Coordinates: (12/22)
* azimuth (azimuth) float64 3kB 0.5 1.5 2.5 ... 357.5 358.5 359.5
elevation (azimuth) float64 3kB ...
time (azimuth) datetime64[ns] 3kB ...
* range (range) float32 4kB 50.0 150.0 ... 9.985e+04 9.995e+04
x (azimuth, range) float64 3MB ...
y (azimuth, range) float64 3MB ...
... ...
crs_wkt int64 8B ...
band int64 8B ...
spatial_ref int64 8B ...
stdev float64 8B ...
NOISE_LEVEL float64 8B ...
alpha float64 8B ...
Data variables: (12/55)
KDP (azimuth, range) float32 1MB ...
PHIDP (azimuth, range) float32 1MB ...
DBZH (azimuth, range) float32 1MB ...
DBZV (azimuth, range) float32 1MB ...
RHOHV (azimuth, range) float32 1MB ...
DBTH (azimuth, range) float32 1MB ...
... ...
AH (azimuth, range) float64 3MB ...
KDP_AH (azimuth, range) float64 3MB ...
PHIDP_CORR5 (azimuth, range) float64 3MB ...
DBTH_CORR5 (azimuth, range) float64 3MB ...
DBZH_CORR5 (azimuth, range) float64 3MB ...
ZDR_CORR5 (azimuth, range) float64 3MB ...Load Sounding Data#
# http://weather.uwyo.edu/upperair/sounding.html
rs_time_s = dt.datetime(2014, 10, 7, 2, 0)
rs_time_c = dt.datetime(2013, 7, 1, 12, 0)
import urllib
try:
rs_data_s, rs_meta_s = wrl.io.get_radiosonde(10410, rs_time_s, cols=(0, 1, 2))
rs_data_c, rs_meta_c = wrl.io.get_radiosonde(10410, rs_time_c, cols=(0, 1, 2))
print("downloaded from UWYO")
except urllib.error.HTTPError:
raise
print(rs_meta_s, rs_meta_c)
downloaded from UWYO
{'Station identifier': 'EDZE', 'Station number': 10410, 'Observation time': datetime.datetime(2014, 10, 7, 0, 0), 'Station latitude': 51.4, 'Station longitude': 6.97, 'Station elevation': 147.0, 'Showalter index': 7.79, 'Lifted index': 4.55, 'LIFT computed using virtual temperature': 4.63, 'SWEAT index': 204.28, 'K index': 22.9, 'Cross totals index': 14.7, 'Vertical totals index': 24.7, 'Totals totals index': 39.4, 'Convective Available Potential Energy': 28.92, 'CAPE using virtual temperature': 36.38, 'Convective Inhibition': -70.37, 'CINS using virtual temperature': -11.48, 'Equilibrum Level': 689.06, 'Equilibrum Level using virtual temperature': 688.7, 'Level of Free Convection': 766.58, 'LFCT using virtual temperature': 881.01, 'Bulk Richardson Number': 1.33, 'Bulk Richardson Number using CAPV': 1.68, 'Temp [K] of the Lifted Condensation Level': 282.6, 'Pres [hPa] of the Lifted Condensation Level': 913.15, 'Equivalent potential temp [K] of the LCL': 313.42, 'Mean mixed layer potential temperature': 290.05, 'Mean mixed layer mixing ratio': 8.2, '1000 hPa to 500 hPa thickness': 5547.0, 'Precipitable water [mm] for entire sounding': 24.77, 'quantity': {'PRES': 'hPa', 'HGHT': 'm', 'TEMP': 'C'}} {'Station identifier': 'EDZE', 'Station number': 10410, 'Observation time': datetime.datetime(2013, 7, 1, 12, 0), 'Station latitude': 51.4, 'Station longitude': 6.97, 'Station elevation': 147.0, 'Showalter index': 6.1, 'Lifted index': 0.57, 'LIFT computed using virtual temperature': 0.51, 'SWEAT index': 77.7, 'K index': 11.7, 'Cross totals index': 13.7, 'Vertical totals index': 28.7, 'Totals totals index': 42.4, 'Convective Available Potential Energy': 7.03, 'CAPE using virtual temperature': 18.0, 'Convective Inhibition': 0.0, 'CINS using virtual temperature': 0.0, 'Equilibrum Level': 597.47, 'Equilibrum Level using virtual temperature': 589.23, 'Level of Free Convection': 931.56, 'LFCT using virtual temperature': 934.17, 'Bulk Richardson Number': 0.24, 'Bulk Richardson Number using CAPV': 0.62, 'Temp [K] of the Lifted Condensation Level': 284.17, 'Pres [hPa] of the Lifted Condensation Level': 934.17, 'Equivalent potential temp [K] of the LCL': 315.07, 'Mean mixed layer potential temperature': 289.76, 'Mean mixed layer mixing ratio': 8.92, '1000 hPa to 500 hPa thickness': 5543.0, 'Precipitable water [mm] for entire sounding': 19.02, 'quantity': {'PRES': 'hPa', 'HGHT': 'm', 'TEMP': 'C'}}
Extract Temperature Profile#
itemp_s = rp.get_temperature_profile(rs_data_s)
itemp_c = rp.get_temperature_profile(rs_data_c)
Plot Temperature Profile#
fig = plt.figure(figsize=(2.5, 5))
ax = fig.add_subplot(111)
itemp_s.plot(y="height", ax=ax, zorder=0, label="stratiform")
itemp_c.plot(y="height", ax=ax, zorder=0, label="convective")
plt.legend()
ax.grid(True)
Merge Temperature Profile#
hmc_s = sweep_s.pipe(rp.merge_radar_profile, itemp_s)
hmc_c = sweep_c.pipe(rp.merge_radar_profile, itemp_c)
display(hmc_s)
display(hmc_c)
<xarray.Dataset> Size: 144MB
Dimensions: (azimuth: 360, range: 1000)
Coordinates: (12/23)
* azimuth (azimuth) float64 3kB 0.5 1.5 2.5 ... 357.5 358.5 359.5
elevation (azimuth) float64 3kB ...
time (azimuth) datetime64[ns] 3kB ...
* range (range) float32 4kB 50.0 150.0 ... 9.985e+04 9.995e+04
x (azimuth, range) float64 3MB ...
y (azimuth, range) float64 3MB ...
... ...
crs_wkt int64 8B ...
band int64 8B ...
spatial_ref int64 8B ...
stdev float64 8B ...
NOISE_LEVEL float64 8B ...
alpha float64 8B ...
Data variables: (12/56)
KDP (azimuth, range) float32 1MB ...
PHIDP (azimuth, range) float32 1MB ...
DBZH (azimuth, range) float32 1MB ...
DBZV (azimuth, range) float32 1MB ...
RHOHV (azimuth, range) float32 1MB ...
DBTH (azimuth, range) float32 1MB ...
... ...
KDP_AH (azimuth, range) float64 3MB ...
PHIDP_CORR5 (azimuth, range) float64 3MB ...
DBTH_CORR5 (azimuth, range) float64 3MB ...
DBZH_CORR5 (azimuth, range) float64 3MB ...
ZDR_CORR5 (azimuth, range) float64 3MB ...
TEMP (azimuth, range) float64 3MB 15.0 15.0 ... -10.29 -10.33<xarray.Dataset> Size: 144MB
Dimensions: (azimuth: 360, range: 1000)
Coordinates: (12/23)
* azimuth (azimuth) float64 3kB 0.5 1.5 2.5 ... 357.5 358.5 359.5
elevation (azimuth) float64 3kB ...
time (azimuth) datetime64[ns] 3kB ...
* range (range) float32 4kB 50.0 150.0 ... 9.985e+04 9.995e+04
x (azimuth, range) float64 3MB ...
y (azimuth, range) float64 3MB ...
... ...
crs_wkt int64 8B ...
band int64 8B ...
spatial_ref int64 8B ...
stdev float64 8B ...
NOISE_LEVEL float64 8B ...
alpha float64 8B ...
Data variables: (12/56)
KDP (azimuth, range) float32 1MB ...
PHIDP (azimuth, range) float32 1MB ...
DBZH (azimuth, range) float32 1MB ...
DBZV (azimuth, range) float32 1MB ...
RHOHV (azimuth, range) float32 1MB ...
DBTH (azimuth, range) float32 1MB ...
... ...
KDP_AH (azimuth, range) float64 3MB ...
PHIDP_CORR5 (azimuth, range) float64 3MB ...
DBTH_CORR5 (azimuth, range) float64 3MB ...
DBZH_CORR5 (azimuth, range) float64 3MB ...
ZDR_CORR5 (azimuth, range) float64 3MB ...
TEMP (azimuth, range) float64 3MB 17.4 17.4 ... -12.64 -12.67HMC Workflow#
switch between stratiform and convective processing here
# hmc_ds = hmc_s.copy()
hmc_ds = hmc_c.copy()
# unify masks
hmc_ds = hmc_ds.where(
~np.isnan(hmc_ds.DBZH_CORR1)
& ~np.isnan(hmc_ds.ZDR_CORR1)
& ~np.isnan(hmc_ds.RHOHV_NC)
& ~np.isnan(hmc_ds.KDP_VULP)
& ~np.isnan(hmc_ds.TEMP)
)
Setup Independent Observable \(Z_H\)#
Retrieve membership function values based on independent observable
%%time
msf_val = msf.wrl.classify.msf_index_indep(hmc_ds.DBZH_CORR1)
display(msf_val)
<xarray.DataArray 'msf_index_indep' (hmc: 11, obs: 5, azimuth: 360,
range: 1000, trapezoid: 4)> Size: 634MB
array([[[[[0., 0., 0., 0.],
[0., 0., 0., 0.],
[0., 0., 0., 0.],
...,
[0., 0., 0., 0.],
[0., 0., 0., 0.],
[0., 0., 0., 0.]],
[[0., 0., 0., 0.],
[0., 0., 0., 0.],
[0., 0., 0., 0.],
...,
[0., 0., 0., 0.],
[0., 0., 0., 0.],
[0., 0., 0., 0.]],
[[0., 0., 0., 0.],
[0., 0., 0., 0.],
[0., 0., 0., 0.],
...,
...
...,
[0., 0., 0., 0.],
[0., 0., 0., 0.],
[0., 0., 0., 0.]],
[[0., 0., 0., 0.],
[0., 0., 0., 0.],
[0., 0., 0., 0.],
...,
[0., 0., 0., 0.],
[0., 0., 0., 0.],
[0., 0., 0., 0.]],
[[0., 0., 0., 0.],
[0., 0., 0., 0.],
[0., 0., 0., 0.],
...,
[0., 0., 0., 0.],
[0., 0., 0., 0.],
[0., 0., 0., 0.]]]]], shape=(11, 5, 360, 1000, 4))
Coordinates: (12/25)
* hmc (hmc) <U2 88B 'LR' 'MR' 'HR' 'LD' 'HL' ... 'DS' 'WS' 'HC' 'VC'
* obs (obs) object 40B 'ZH' 'ZDR' 'RHO' 'KDP' 'TEMP'
* azimuth (azimuth) float64 3kB 0.5 1.5 2.5 3.5 ... 357.5 358.5 359.5
elevation (azimuth) float64 3kB 2.395 2.395 2.395 ... 2.395 2.395 2.395
time (azimuth) datetime64[ns] 3kB 2013-07-01T15:43:26 ... 2013-07...
* range (range) float32 4kB 50.0 150.0 250.0 ... 9.985e+04 9.995e+04
... ...
crs_wkt int64 8B 0
band int64 8B 1
spatial_ref int64 8B 0
stdev float64 8B 0.00471
NOISE_LEVEL float64 8B -27.0
alpha float64 8B 0.28
Dimensions without coordinates: trapezoid
Attributes:
version: 1
title: 2D Membershipfunctions Hydrometeorclassification for XBand
institution: Institute of Geosciences, Meteorology Section, University o...
history: created by Raquel Evaristo, adapted to netCDF by Kai Mühlbauer
comment: created with wradlibCPU times: user 137 ms, sys: 162 ms, total: 299 ms
Wall time: 298 ms
Fuzzyfication#
fu = msf_val.wrl.classify.fuzzyfi(
hmc_ds,
dict(ZH="DBZH_CORR1", ZDR="ZDR_CORR1", RHO="RHOHV_NC", KDP="KDP_VULP", TEMP="TEMP"),
)
fu = fu.chunk({"hmc": 1})
display(fu)
<xarray.DataArray 'fuzzyfi' (hmc: 11, obs: 5, azimuth: 360, range: 1000)> Size: 158MB
dask.array<xarray-<this-array>, shape=(11, 5, 360, 1000), dtype=float64, chunksize=(1, 5, 360, 1000), chunktype=numpy.ndarray>
Coordinates: (12/25)
* hmc (hmc) <U2 88B 'LR' 'MR' 'HR' 'LD' 'HL' ... 'DS' 'WS' 'HC' 'VC'
* obs (obs) object 40B 'ZH' 'ZDR' 'RHO' 'KDP' 'TEMP'
* azimuth (azimuth) float64 3kB 0.5 1.5 2.5 3.5 ... 357.5 358.5 359.5
elevation (azimuth) float64 3kB dask.array<chunksize=(360,), meta=np.ndarray>
time (azimuth) datetime64[ns] 3kB dask.array<chunksize=(360,), meta=np.ndarray>
* range (range) float32 4kB 50.0 150.0 250.0 ... 9.985e+04 9.995e+04
... ...
crs_wkt int64 8B 0
band int64 8B 1
spatial_ref int64 8B 0
stdev float64 8B 0.00471
NOISE_LEVEL float64 8B -27.0
alpha float64 8B 0.28
Attributes:
version: 1
title: 2D Membershipfunctions Hydrometeorclassification for XBand
institution: Institute of Geosciences, Meteorology Section, University o...
history: created by Raquel Evaristo, adapted to netCDF by Kai Mühlbauer
comment: created with wradlibScore#
# weights dataset
w = xr.Dataset(dict(ZH=2.0, ZDR=1.0, RHO=1.0, KDP=1.0, TEMP=1.0))
display(w)
<xarray.Dataset> Size: 40B
Dimensions: ()
Data variables:
ZH float64 8B 2.0
ZDR float64 8B 1.0
RHO float64 8B 1.0
KDP float64 8B 1.0
TEMP float64 8B 1.0score = fu.wrl.classify.probability(w).compute()
display(score)
<xarray.DataArray (hmc: 11, azimuth: 360, range: 1000)> Size: 32MB
array([[[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.],
...,
[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.]],
[[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.],
...,
[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.]],
[[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.],
...,
...
...,
[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.]],
[[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.],
...,
[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.]],
[[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.],
...,
[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.]]], shape=(11, 360, 1000))
Coordinates: (12/24)
* hmc (hmc) <U2 88B 'LR' 'MR' 'HR' 'LD' 'HL' ... 'DS' 'WS' 'HC' 'VC'
* azimuth (azimuth) float64 3kB 0.5 1.5 2.5 3.5 ... 357.5 358.5 359.5
elevation (azimuth) float64 3kB 2.395 2.395 2.395 ... 2.395 2.395 2.395
time (azimuth) datetime64[ns] 3kB 2013-07-01T15:43:26 ... 2013-07...
* range (range) float32 4kB 50.0 150.0 250.0 ... 9.985e+04 9.995e+04
x (azimuth, range) float64 3MB 0.4359 1.308 ... -870.1 -871.0
... ...
crs_wkt int64 8B 0
band int64 8B 1
spatial_ref int64 8B 0
stdev float64 8B 0.00471
NOISE_LEVEL float64 8B -27.0
alpha float64 8B 0.28
Attributes:
version: 1
title: 2D Membershipfunctions Hydrometeorclassification for XBand
institution: Institute of Geosciences, Meteorology Section, University o...
history: created by Raquel Evaristo, adapted to netCDF by Kai Mühlbauer
comment: created with wradlibClassification#
cl_res = score.wrl.classify.classify(threshold=0.0)
display(cl_res)
<xarray.DataArray (hmc: 12, azimuth: 360, range: 1000)> Size: 35MB
array([[[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.],
...,
[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.]],
[[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.],
...,
[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.]],
[[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.],
...,
...
...,
[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.]],
[[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.],
...,
[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.]],
[[1., 1., 1., ..., 1., 1., 1.],
[1., 1., 1., ..., 1., 1., 1.],
[1., 1., 1., ..., 1., 1., 1.],
...,
[1., 1., 1., ..., 1., 1., 1.],
[1., 1., 1., ..., 1., 1., 1.],
[1., 1., 1., ..., 1., 1., 1.]]], shape=(12, 360, 1000))
Coordinates: (12/24)
* hmc (hmc) <U2 96B 'LR' 'MR' 'HR' 'LD' 'HL' ... 'WS' 'HC' 'VC' 'NP'
* azimuth (azimuth) float64 3kB 0.5 1.5 2.5 3.5 ... 357.5 358.5 359.5
elevation (azimuth) float64 3kB 2.395 2.395 2.395 ... 2.395 2.395 2.395
time (azimuth) datetime64[ns] 3kB 2013-07-01T15:43:26 ... 2013-07...
* range (range) float32 4kB 50.0 150.0 250.0 ... 9.985e+04 9.995e+04
x (azimuth, range) float64 3MB 0.4359 1.308 ... -870.1 -871.0
... ...
crs_wkt int64 8B 0
band int64 8B 1
spatial_ref int64 8B 0
stdev float64 8B 0.00471
NOISE_LEVEL float64 8B -27.0
alpha float64 8B 0.28
Attributes:
version: 1
title: 2D Membershipfunctions Hydrometeorclassification for XBand
institution: Institute of Geosciences, Meteorology Section, University o...
history: created by Raquel Evaristo, adapted to netCDF by Kai Mühlbauer
comment: created with wradlibPlot HMC Results#
Plot Score of HMC Types#
# score = score.assign_coords(hmc=np.array(list(pr_types.values())).T[1][:11])
score = score.where(score > 0)
score.plot(
x="x",
y="y",
col="hmc",
col_wrap=4,
cmap="HomeyerRainbow",
cbar_kwargs=dict(label="Score"),
subplot_kws=dict(xlim=(-100e3, 100e3), ylim=(-100e3, 100e3), xlabel="Range (m)"),
)
<xarray.plot.facetgrid.FacetGrid at 0x7f4102c782f0>
Plot maximum score#
sort score and calculate difference between the winner and the other classes!
fig = plt.figure(figsize=(10, 8))
ax = fig.add_subplot(111)
cl_res.max("hmc").plot(
x="x", y="y", cmap="HomeyerRainbow", ax=ax, cbar_kwargs=dict(label="Score")
)
ax.set_xlabel("Range [m]")
ax.set_ylabel("Range [m]")
ax.set_xlim(-100e3, 100e3)
ax.set_ylim(-100e3, 100e3)
t = ax.set_title("Hydrometeorclassification")
t.set_y(1.1)
Plot classification result#
hydro = cl_res.argmax("hmc")
hydro.attrs = dict(long_name="Hydrometeorclassification")
display(hydro)
<xarray.DataArray (azimuth: 360, range: 1000)> Size: 3MB
array([[11, 11, 11, ..., 11, 11, 11],
[11, 11, 11, ..., 11, 11, 11],
[11, 11, 11, ..., 11, 11, 11],
...,
[11, 11, 11, ..., 11, 11, 11],
[11, 11, 11, ..., 11, 11, 11],
[11, 11, 11, ..., 11, 11, 11]], shape=(360, 1000))
Coordinates: (12/23)
* azimuth (azimuth) float64 3kB 0.5 1.5 2.5 3.5 ... 357.5 358.5 359.5
elevation (azimuth) float64 3kB 2.395 2.395 2.395 ... 2.395 2.395 2.395
time (azimuth) datetime64[ns] 3kB 2013-07-01T15:43:26 ... 2013-07...
* range (range) float32 4kB 50.0 150.0 250.0 ... 9.985e+04 9.995e+04
x (azimuth, range) float64 3MB 0.4359 1.308 ... -870.1 -871.0
y (azimuth, range) float64 3MB 49.95 149.9 ... 9.97e+04 9.98e+04
... ...
crs_wkt int64 8B 0
band int64 8B 1
spatial_ref int64 8B 0
stdev float64 8B 0.00471
NOISE_LEVEL float64 8B -27.0
alpha float64 8B 0.28
Attributes:
long_name: Hydrometeorclassificationhmc = rp.visdict14["HMC"]
cmap = hmc["cmap"]
norm = hmc["norm"]
fig = plt.figure(figsize=(10, 8))
ax = fig.add_subplot(111)
# prepare colorbar
cbar_kwargs = dict(ticks=hmc["ticks"], norm=norm, extend="neither")
im = hydro.plot(
x="x",
y="y",
ax=ax,
levels=hmc["ticks"],
cmap=hmc["cmap"],
norm=norm,
cbar_kwargs=cbar_kwargs,
xlim=(-100e3, 100e3),
ylim=(-100e3, 100e3),
)
# override colorbar ticklabels
labels = pr_types.values() # [i][1] for i, _ in enumerate(pr_types)]
labels = im.colorbar.ax.set_yticklabels(labels)
zlevels = rp.visdict14["ZH"]["ticks"]
zdrlevels = rp.visdict14["ZDR"]["ticks"]
rholevels = rp.visdict14["RHO"]["ticks"]
kdplevels = rp.visdict14["KDP"]["ticks"]
philevels = rp.visdict14["PHI"]["ticks"]
hmclevels = rp.visdict14["HMC"]["ticks"]
levels = lambda x: dict(levels=x, cbar_kwargs=dict(ticks=x))
_kwargs = dict(
x="x", y="y", xlim=(-100e3, 100e3), ylim=(-100e3, 100e3), cmap="HomeyerRainbow"
)
fig = plt.figure(figsize=(16, 20))
ax1 = fig.add_subplot(321)
kwargs = _kwargs | levels(zlevels) | dict(ax=ax1)
hmc_ds.DBZH_CORR1.plot.contourf(**kwargs)
ax1.set_title(hmc_ds.DBZH_CORR1.attrs["long_name"])
ax2 = fig.add_subplot(322)
zdrlevels2 = np.arange(0, 5, 0.2)
kwargs = _kwargs | levels(zdrlevels2) | dict(ax=ax2)
hmc_ds.ZDR_CORR1.plot.contourf(**kwargs)
ax2.set_title(hmc_ds.ZDR_CORR1.attrs["long_name"])
ax3 = fig.add_subplot(323)
kwargs = _kwargs | levels(rholevels) | dict(ax=ax3)
hmc_ds.RHOHV_NC.plot.contourf(**kwargs)
ax3.set_title(hmc_ds.RHOHV_NC.attrs["long_name"])
ax4 = fig.add_subplot(324)
# philevels2 = np.arange(0, 15, 1)
# kwargs = _kwargs | levels(philevels2) | dict(ax=ax4)
# hmc_ds.PHIDP_CORR1.plot.contourf(**kwargs)
# ax4.set_title(hmc_ds.PHIDP_CORR2.attrs["long_name"])
kwargs = _kwargs | levels(kdplevels) | dict(ax=ax4)
hmc_ds.KDP_VULP.plot(**kwargs)
ax4.set_title(hmc_ds.KDP_VULP.attrs["long_name"])
ax5 = fig.add_subplot(325)
templevels = None
kwargs = _kwargs | levels(templevels) | dict(ax=ax5) | dict(cmap="seismic")
hmc_ds.TEMP.plot(**kwargs)
ax5.set_title(hmc_ds.TEMP.attrs["long_name"])
ax6 = fig.add_subplot(326)
cbar_kwargs = dict(ticks=hmc["ticks"], norm=hmc["norm"], extend="neither")
kwargs = (
_kwargs
| levels(hmclevels)
| dict(ax=ax6)
| dict(norm=hmc["norm"], cmap=hmc["cmap"])
)
im = hydro.plot(**kwargs)
ax6.set_title(hydro.attrs["long_name"])
# override colorbar ticklabels
labels = pr_types.values() # [i][1] for i, _ in enumerate(pr_types)]
labels = im.colorbar.ax.set_yticklabels(labels)
fig.tight_layout()