1
+ # Author: Niels S Hvidberg
2
+ # Description: Python program, converted from
3
+ # a jupyter notebook.
4
+
5
+ # Import packages
6
+ import numpy as np
7
+ import xarray as xr
8
+ import cartopy .crs as ccrs
9
+ import matplotlib .pyplot as plt
10
+ import datetime as dt
11
+ from mpl_toolkits .axes_grid1 import make_axes_locatable
12
+
13
+ # Printing text in colors
14
+ class bcolors :
15
+ HEADER = '\033 [95m'
16
+ OKBLUE = '\033 [94m'
17
+ OKCYAN = '\033 [96m'
18
+ OKGREEN = '\033 [92m'
19
+ WARNING = '\033 [93m'
20
+ FAIL = '\033 [91m'
21
+ ENDC = '\033 [0m'
22
+ BOLD = '\033 [1m'
23
+ UNDERLINE = '\033 [4m'
24
+
25
+ def show (xr_dataset ):
26
+ """
27
+ This function gives you a way to display xarray datasets per command, instead of implicitly
28
+ by calling the dataset instance as the last thing in a cell.
29
+ """
30
+ from IPython .display import display , HTML
31
+ display (HTML (xr .core .formatting_html .dataset_repr (xr_dataset )))
32
+
33
+ def xr_open_old (data_dir , days = [1 , 31 ], hours = [0 , 23 ]):
34
+ infile = []
35
+ dataset = []
36
+ for i in range (days [0 ], days [1 ]+ 1 ):
37
+ if (i == 1 ):
38
+ z = 1
39
+ else :
40
+ z = 0
41
+
42
+ for j in range (z + hours [0 ], hours [1 ]+ 1 ):
43
+ name = f'201101{ i :02d} { j :02d} .nc'
44
+ infile .append (data_dir + '/' + name )
45
+ dataset .append (xr .open_dataset (infile [- 1 ]))
46
+
47
+ return dataset
48
+
49
+ def xr_open (data_dir , days = [1 , 31 ], hours = [0 , 23 ]):
50
+ infile = []
51
+ dataset = []
52
+ for i in range (days [0 ], days [1 ]+ 1 ):
53
+ if (i == 1 ):
54
+ z = 1
55
+ else :
56
+ z = 0
57
+
58
+ for j in range (z + hours [0 ], hours [1 ]+ 1 ):
59
+ name = f'1_201101{ i :02d} { j :02d} .nc'
60
+ infile .append (data_dir + '/' + name )
61
+ dataset .append (xr .open_dataset (infile [- 1 ]))
62
+
63
+ return dataset
64
+
65
+ def dehm_plotter (dataset , index = 12 , meandim = 'z' , species = "CO2.01" , close = False , central_longitude = - 32 , output_dir = 'frames' ):
66
+ """
67
+ Docstring for dehm_plotter:
68
+ This function is used to plot netCDF files (output from DEHM) on a polar
69
+ stereographic map.
70
+
71
+ dataset: A list of xarray-dataset objects with 3D field data.
72
+ index: The index for the specific dataset to workwith in dataset list.
73
+ meandim: Calculate the mean over this dimension. Most often 'time' or 'z'.
74
+ species: the kind to plot. For DEHM CO2 the tracers are called CO2.ntrac
75
+ (1 indexing!).
76
+
77
+ The function creates a plot, saves it and can also close the plot again. The
78
+ plot is saved under the name:
79
+
80
+ f'{output_dir}/frame{index:03d}.png'
81
+ """
82
+ if meandim :
83
+ da = dataset [index ][species ].mean (dim = meandim )
84
+ else :
85
+ da = dataset [index ][species ].isel (z = 0 )
86
+
87
+ lat , lon = dataset [index ]['lat' ].values , dataset [index ]['lon' ].values
88
+
89
+ # Get values
90
+ pdata = da .values
91
+
92
+ # Set min/max values for plots:
93
+ vmin = 0.0
94
+ vmax = 40.0
95
+
96
+ # This is the map projection we want to plot *onto*
97
+ map_proj = ccrs .NorthPolarStereo (central_longitude = central_longitude )
98
+ fig , ax = plt .subplots (subplot_kw = {'projection' : map_proj }, figsize = (7 ,7 ))
99
+
100
+ # Set coastline appearance
101
+ ax .coastlines (color = 'black' ,zorder = 2 ,alpha = 1 ,linewidth = 1.5 )
102
+
103
+ # Set gridlines appearance
104
+ gl = ax .gridlines (draw_labels = True , zorder = 1 , alpha = 0.7 , linewidth = 1 , crs = ccrs .PlateCarree ())
105
+
106
+ # Set label style
107
+ gl .xlabel_style = {'size' :7 }
108
+ gl .ylabel_style = {'size' :7 }
109
+
110
+ # Set colormap
111
+ cmap = plt .get_cmap ('jet' )
112
+ cmap .set_bad ('w' ,1.0 )
113
+
114
+ # Plot image
115
+ im = ax .pcolormesh (lon ,
116
+ lat ,
117
+ pdata ,
118
+ cmap = cmap ,
119
+ vmin = vmin , # Min value for colormap (especially used for videos)
120
+ vmax = vmax , # Max value for colormap
121
+ transform = ccrs .PlateCarree (),
122
+ zorder = 0 , # ?
123
+ shading = 'auto' )
124
+
125
+ # Colorbar
126
+ fig .colorbar (im , ax = ax )
127
+
128
+ # Check if plot should be closed and saved instead of shown (Used for creating frames)
129
+ if close :
130
+ plt .savefig (f'{ output_dir } /frame{ index :03d} .png' )
131
+ plt .close (fig )
132
+
133
+ def make_frames_from_list (dataset , meandim , species , central_longitude = - 32 , output_dir = 'frames' ):
134
+ index = 0
135
+ for i in range (1 ,32 ):
136
+ if (i == 1 ):
137
+ z = 1
138
+ else :
139
+ z = 0
140
+
141
+ for j in range (z ,24 ):
142
+ dehm_plotter (dataset = dataset , index = index , meandim = meandim , species = species , close = True , central_longitude = central_longitude , output_dir = output_dir )
143
+ index += 1
144
+
145
+ ## END OF DEFINITIONS #########################################################################
146
+ # Choose case and scroll down to the relevant section
147
+ case = 11
148
+
149
+ # DEHM data
150
+ if case == 1 :
151
+ dir1 = 'netcdf1'
152
+ dir2 = 'netcdf2'
153
+ dir3 = 'netcdf3'
154
+ dir4 = 'netcdf4'
155
+
156
+ ds1 = xr_open_old (dir1 )
157
+ ds2 = xr_open_old (dir2 )
158
+ ds3 = xr_open_old (dir3 )
159
+ ds4 = xr_open_old (dir4 )
160
+ ds = ds1
161
+ show (ds [0 ])
162
+
163
+ if case == 11 :
164
+ dir1 = 'only_cams_glob/2011/netcdf'
165
+ dir2 = 'only_jena_ocn/2011/netcdf'
166
+
167
+ ds1 = xr_open (dir1 )
168
+ ds2 = xr_open (dir1 )
169
+ ds = ds1
170
+ show (ds [0 ])
171
+
172
+ # CAMS data
173
+ if case == 2 :
174
+ infile_cams = '/home/niels/Documents/Data/CAMS/CAMS-GLOB/CAMS-GLOB-ANT_Glb_0.1x0.1_anthro_co2_excl_short-cycle_org_C_v5.3_monthly.nc'
175
+ ds_cams = xr .open_dataset (infile_cams )
176
+ ds = ds_cams
177
+ show (ds )
178
+
179
+ # Jena data
180
+ if case == 3 :
181
+ infile_jena = '/home/niels/Documents/Data/JENA/oc_v2023.pCO2.nc'
182
+ ds_jena = xr .open_dataset (infile_jena )
183
+ ds = ds_jena
184
+ show (ds )
185
+
186
+ ## END OF DATA SELECTION, BEGINNING OF SPECIFIC CODE ##########################################
187
+
188
+ species = f'CO2.{ 1 :02d} '
189
+ meandim = []
190
+ central_longitude = - 32
191
+
192
+ dehm_plotter (dataset = ds2 ,
193
+ index = 100 ,
194
+ meandim = meandim ,
195
+ species = species ,
196
+ close = False ,
197
+ central_longitude = central_longitude ,
198
+ )
199
+
200
+ if True :
201
+ make_frames_from_list (dataset = ds1 , meandim = meandim , species = species , central_longitude = central_longitude , output_dir = 'frames1' )
202
+ make_frames_from_list (dataset = ds2 , meandim = meandim , species = species , central_longitude = central_longitude , output_dir = 'frames2' )
203
+ #make_frames_from_list(dataset=ds3, meandim=meandim, species=species, central_longitude=central_longitude, output_dir='frames3')
204
+ #make_frames_from_list(dataset=ds4, meandim=meandim, species=species, central_longitude=central_longitude, output_dir='frames4')
205
+
206
+ #!./make_video 1
207
+ #!./make_video 2
0 commit comments