1
- #Load libraries
2
- import xarray as xr
3
- import numpy as np
4
- import pandas as pd
5
- #import eccodes
6
- from sklearn .cluster import KMeans
7
- from sklearn .decomposition import PCA
8
- import cartopy .crs as ccrs
9
- from cartopy import feature
10
- import matplotlib .pyplot as plt
11
- from matplotlib .colors import LinearSegmentedColormap
12
- # key PyWR functions are imported here
13
- from PyWR import *
1
+ #driver file
2
+ import os
3
+ import glob
14
4
15
-
16
- #The data used in this diagnostic was downloaded from the IRI:
17
- #https://iridl.ldeo.columbia.edu/?Set-Language=en
18
- #If data of a similar nature is desired, refer to the prep_data.py file for instructions on how
19
- #to download anomaly data from the http server
20
-
21
- #need to be changed to where the files are located in framework
22
- reanalysis = xr .open_dataset ('WUS/data/hgt_NNRP_rean.nc' , decode_cf = True , decode_times = True ).stack (time = ['T' ], grid = ['Y' , 'X' ])
23
- rainfall = xr .open_dataset ('WUS/data/rainfall_cpc.nc' , decode_cf = True , decode_times = True ).stack (time = ['T' ], grid = ['Y' , 'X' ])
24
- t2m = xr .open_dataset ('WUS/data/t2m_cpc.nc' , decode_cf = True , decode_times = True ).stack (time = ['T' ], grid = ['Y' , 'X' ])
25
- uwnd = xr .open_dataset ('WUS/data/u_NNRP_rean.nc' , decode_cf = True , decode_times = True ).stack (time = ['T' ], grid = ['Y' , 'X' ])
26
- uwnd = xr .open_dataset ('WUS/data/v_NNRP_rean.nc' , decode_cf = True , decode_times = True ).stack (time = ['T' ], grid = ['Y' , 'X' ])
27
-
28
- #get rid of dummy pressure coordinate
29
- reanalysis = reanalysis .isel (P = 0 )
30
- uwnd = uwnd .isel (P = 0 )
31
- vwnd = vwnd .isel (P = 0 )
32
-
33
-
34
- #viewing the data
35
- print (reanalysis )
36
- print (rainfall )
37
- print (t2m )
38
- print (vwnd )
39
- print (uwnd )
40
-
41
-
42
- #DIMENSION REDUCTION: choose a percentage of variance explained that we will require
43
- n_eof = get_number_eof (X = reanalysis ['adif' ].values , var_to_explain = 0.9 , plot = True )
44
-
45
- #project the data onto the leading EOFs to get the principal component time series
46
- #We will retain the PCA model for use later. The reanalysis_pc variable is now indexed [time, EOF]
47
- pca_model = PCA (n_components = n_eof ).fit (reanalysis ['adif' ].values )
48
- reanalysis_pc = pca_model .transform (reanalysis ['adif' ].values )
49
-
50
-
51
- #REANALYSIS WEATHER TYPING: perform the clustering. We will manually specify the number of clusters we want to create and the number of simulations we want to run
52
- ncluster = 6 # use 6 WTs
53
- n_sim = 50 # typically 25-50 -- try 25 for quick preliminary computation only
54
-
55
- centroids , wtypes = loop_kmeans (X = reanalysis_pc , n_cluster = ncluster , n_sim = n_sim )
56
- class_idx , best_part = get_classifiability_index (centroids )
57
- print ('The classifiability index is {}' .format (class_idx ))
58
-
59
-
60
- #Now that we have identified a suitable partition, we can use it to keep only the corresponding centroid and set of weather type labels. Use centroids to define KMeans object
61
- best_fit = KMeans (n_clusters = ncluster , init = centroids [best_part , :, :], n_init = 1 , max_iter = 1 ).fit (reanalysis_pc )
62
-
63
- # start with reanalysis
64
- reanalysis_composite = reanalysis .copy ()
65
- model_clust = best_fit .fit_predict (reanalysis_pc ) # get centroids
66
- weather_types = xr .DataArray (
67
- model_clust ,
68
- coords = {'time' : reanalysis_composite ['time' ]},
69
- dims = 'time'
70
- )
71
- reanalysis_composite ['WT' ] = weather_types
72
- reanalysis_composite = reanalysis_composite .groupby ('WT' ).mean (dim = 'time' ).unstack ('grid' )['adif' ]
73
- reanalysis_composite ['M' ] = 0
74
-
75
- wt_anomalies = [] # initialize empty list
76
- wt_anomalies .append (reanalysis_composite )
77
-
78
- wt_anomalies = xr .concat (wt_anomalies , dim = 'M' ) # join together
79
- wt_anomalies ['WT' ] = wt_anomalies ['WT' ] + 1 # start from 1
80
-
81
-
82
- #FIGURE: prepare a figure with rainfall and temperature composites
83
- #Hashed out options for adding wind arrows, and additional plot labels
84
-
85
- X , Y = np .meshgrid (reanalysis ['adif' ].X , reanalysis ['adif' ].Y )
86
- map_proj = ccrs .PlateCarree () #ccrs.Orthographic(-110, 10)
87
- data_proj = ccrs .PlateCarree ()
88
- wt_unique = np .unique (wt_anomalies ['WT' ])
89
- figsize = (14 , 8 )
90
-
91
- #WT proportions
92
- wt = weather_types .to_dataframe (name = 'WT' )
93
- wt = wt + 1
94
- #wt.to_netcdf('data/t2m_cpc.nc', format="NETCDF4")
95
- wt_counts = wt .groupby ('WT' ).size ().div (wt ['WT' ].size )
96
- wt_counts
97
-
98
- xmin ,xmax = reanalysis ['X' ].min (), reanalysis ['X' ].max ()
99
- ymin ,ymax = reanalysis ['Y' ].min (), reanalysis ['Y' ].max ()
100
-
101
- # Set up the Figure
102
- plt .rcParams .update ({'font.size' : 12 })
103
- fig , axes = plt .subplots (
104
- nrows = 3 , ncols = len (wt_unique ), subplot_kw = {'projection' : map_proj },
105
- figsize = figsize , sharex = True , sharey = True
106
- )
107
-
108
- # Loop through
109
- for i ,w in enumerate (wt_unique ):
110
- def selector (ds ):
111
- times = wt .loc [wt ['WT' ] == w ].index
112
- ds = ds .sel (time = np .in1d (ds .unstack ('time' )['T' ], times ))
113
- ds = ds .mean (dim = 'time' )
114
- return (ds )
115
-
116
- # Top row: geopotential height anomalies
117
- ax = axes [0 , i ]
118
- ax .set_title ('WT {}: {:.1%} of days' .format (w , wt_counts .values [i ]))
119
- C0 = selector (reanalysis ['adif' ]).unstack ('grid' ).plot .contourf (
120
- transform = data_proj ,
121
- ax = ax ,
122
- cmap = 'PuOr' ,
123
- extend = "both" ,
124
- levels = np .linspace (- 2e2 , 2e2 , 21 ),
125
- add_colorbar = False ,
126
- add_labels = False
127
- )
128
- ax .coastlines ()
129
- ax .add_feature (feature .BORDERS )
130
- #ax.set_extent([-95, -65, -12, 12])
131
-
132
- # # add wind arrows
133
- # U = selector(uwnd).adif.values
134
- # V = selector(vwnd).adif.values
135
- # magnitude = np.sqrt(U**2 + V**2)
136
- # strongest = magnitude > np.percentile(magnitude, 50)
137
- # Q = ax.quiver(
138
- # X[strongest], Y[strongest], U[strongest], V[strongest],
139
- # transform=data_proj,
140
- # width=0.001, scale=0.8,units='xy'
141
- # )
142
-
143
- # Middle row: rainfall anomalies
144
- ax = axes [1 , i ]
145
- C1 = selector (rainfall ['adif' ]).unstack ('grid' ).plot .contourf (
146
- transform = data_proj ,
147
- ax = ax ,
148
- cmap = 'BrBG' ,
149
- extend = "both" ,
150
- levels = np .linspace (- 2 , 2 , 13 ),
151
- add_colorbar = False ,
152
- add_labels = False
153
- )
154
- ax .coastlines ()
155
- ax .add_feature (feature .BORDERS )
156
- #ax.set_extent([-95, -75, -9, 5])
157
-
158
- # Bottom row: tepmperature anomalies
159
- ax = axes [2 , i ]
160
- C2 = selector (t2m ['asum' ]).unstack ('grid' ).plot .contourf (
161
- transform = data_proj ,
162
- ax = ax ,
163
- cmap = 'RdBu_r' ,
164
- extend = "both" ,
165
- levels = np .linspace (- 2 , 2 , 13 ),
166
- add_colorbar = False ,
167
- add_labels = False
168
- )
169
- ax .coastlines ()
170
- ax .add_feature (feature .BORDERS )
171
- #ax.set_extent([-95, -70, -9, 5])
172
- ax .tick_params (colors = 'b' )
173
-
174
- # # Add Colorbar
175
- plt .tight_layout ()
176
- fig .subplots_adjust (right = 0.94 )
177
- cax0 = fig .add_axes ([0.97 , 0.65 , 0.0075 , 0.3 ])
178
- cax1 = fig .add_axes ([0.97 , 0.33 , 0.0075 , 0.3 ])
179
- cax2 = fig .add_axes ([0.97 , 0.01 , 0.0075 , 0.3 ])
180
- cbar0 = fig .colorbar (C0 , cax = cax0 )
181
- cbar0 .formatter .set_powerlimits ((4 , 4 ))
182
- cbar0 .update_ticks ()
183
- cbar0 .set_label (r'$zg_{500}$ anomaly [$m^2$/$s^2$]' , rotation = 270 )
184
- cbar0 .ax .get_yaxis ().labelpad = 20
185
- cbar1 = fig .colorbar (C1 , cax = cax1 )
186
- cbar1 .set_label ('Precip. anomaly [mm/d]' , rotation = 270 )
187
- cbar1 .ax .get_yaxis ().labelpad = 20
188
- cbar2 = fig .colorbar (C2 , cax = cax2 )
189
- cbar2 .set_label ('T2m anomaly [$^o$C]' , rotation = 270 )
190
- cbar2 .ax .get_yaxis ().labelpad = 20
191
-
192
- # Format these axes
193
-
194
-
195
- #Add plot labels
196
- # letters = string.ascii_lowercase
197
- # for i, ax in enumerate(axes.flat):
198
- # label = '({})'.format(letters[i])
199
- # t = ax.text(0.05, 0.9, label, fontsize=11, transform=ax.transAxes)
200
- # t.set_bbox(dict(facecolor='white', edgecolor='gray'))
201
-
202
- # Add a quiver key
203
- #k = plt.quiverkey(Q, 0.9, 0.7, 1, '1 m/s', labelpos='E', coordinates='figure')
204
-
205
- fig .savefig ('figs/wt_composite.pdf' , bbox_inches = 'tight' ) #this needs to be changed to appropriate folder in framework
206
- plt .show ()
5
+ os .environ ["pr_file" ] = os .environ
0 commit comments