FV3-JEDI
fv3jedi_plot_field.py
Go to the documentation of this file.
1 #!/usr/bin/env python3
2 #
3 # (C) Copyright 2020 UCAR
4 #
5 # This software is licensed under the terms of the Apache Licence Version 2.0
6 # which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
7 
8 import cartopy.crs as ccrs
9 import click
10 import matplotlib.pyplot as plt
11 import netCDF4
12 import numpy as np
13 import os
14 
15 # --------------------------------------------------------------------------------------------------
16 ## @package fv3jedi_plot_field.py
17 # This is a utility for plotting an fv3jedi field that has been output on lon/lat grid
18 #
19 # 1. Run the fv3jedi_convertstate.x application outputting a lonlat set of fields. See
20 # fv3-jedi/test/testinput/convertstate_gfs_c2ll.yaml for an example of doing this.
21 #
22 # 2. Run this application with the inputs corresponding to the field and level that you
23 # wish to plot.
24 #
25 # --------------------------------------------------------------------------------------------------
26 
27 def abort(message):
28  print('\n ABORT: '+message+'\n')
29  raise(SystemExit)
30 
31 # --------------------------------------------------------------------------------------------------
32 
33 @click.command()
34 @click.option('--inputfile', required=True, help='NetCDF input containing Lon/Lat fields')
35 @click.option('--fieldname', required=True, help='Name of field to plot')
36 @click.option('--layer', required=False, help='Model layer to plot. [reqiured if 3D variable]', type=int)
37 @click.option('--showfig', required=False, help='Display figure if set to true', default=False)
38 def main(inputfile, fieldname, layer, showfig):
39 
40  # Open the file
41  print('\nOpening ', inputfile, 'for reading')
42  ncfile = netCDF4.Dataset(inputfile, mode='r')
43 
44  # Get metadata from the file
45  npx = ncfile.dimensions["lon"].size
46  npy = ncfile.dimensions["lat"].size
47  npz = ncfile.dimensions["lev"].size
48  lons = ncfile.variables["lons"][:]
49  lats = ncfile.variables["lats"][:]
50 
51  # Print field dimensions
52  print(" Grid dimensions", npx, 'x', npy, 'x', npz)
53 
54  # Get field units from the file
55  units = ncfile.variables[fieldname].units
56 
57  # Zero out array to fill with field
58  field = np.zeros((npy, npx))
59 
60  # Check if field is two or three dimensions
61  if len(ncfile.variables[fieldname].shape) == 4:
62 
63  # User must provide layer/level to plot if 3D
64  if (layer == None):
65  abort("If plotting 3D variable user must provide layer with --layer")
66 
67  # Message and read the field at provided layer
68  print(" Reading layer ", layer, " from field ", fieldname)
69  field[:,:] = ncfile.variables[fieldname][:,layer-1,:,:]
70 
71  # Set plot title and output file to include level plotted
72  title = "Contour of "+fieldname+" ("+units+") for layer "+str(layer)
73  outfile = os.path.splitext(inputfile)[0]+"_"+fieldname+"_layer-"+str(layer)+".png"
74 
75  elif len(ncfile.variables[fieldname].shape) == 3:
76 
77  # Message and read the field at provided layer
78  print(" Reading field ", fieldname)
79  field[:,:] = ncfile.variables[fieldname][:,:]
80  title = "Contour of "+fieldname+" ("+units+")"
81  outfile = os.path.splitext(inputfile)[0]+"_"+fieldname+".png"
82 
83  # Close the file
84  ncfile.close()
85 
86  # Check if field has positve and negative values
87  # ----------------------------------------------
88  if np.min(field) < 0:
89  cmax = np.max(np.abs(field))
90  cmin = -cmax
91  cmap = 'RdBu'
92  else:
93  cmax = np.max(field)
94  cmin = np.min(field)
95  cmap = 'nipy_spectral'
96 
97  levels = np.linspace(cmin,cmax,25)
98 
99  # Create two dimensional contour plot of field
100  # --------------------------------------------
101 
102  # Set the projection
103  projection = ccrs.PlateCarree()
104 
105  # Create figure to hold plot
106  fig = plt.figure(figsize=(10, 5))
107 
108  # Just one subplot for now
109  ax = fig.add_subplot(1, 1, 1, projection=projection)
110 
111  # Contour the field
112  im = ax.contourf(lons, lats, field,
113  transform=projection,
114  cmap=cmap,
115  levels=levels)
116 
117  # Add coast lines to the plot
118  ax.coastlines()
119 
120  # Add labels to the plot
121  ax.set_xticks(np.linspace(-180, 180, 5), crs=projection)
122  ax.set_yticks(np.linspace(-90, 90, 5), crs=projection)
123  ax.set_xlabel('Longitude')
124  ax.set_ylabel('Latitude')
125  ax.set_title(title)
126  ax.set_global()
127 
128  # Add a colorbar for the filled contour.
129  fig.colorbar(im)
130 
131  # Show the figure
132  print(" Saving figure as", outfile, "\n")
133  plt.savefig(outfile)
134  if (showfig):
135  plt.show()
136 
137 
138 # --------------------------------------------------------------------------------------------------
139 
140 if __name__ == '__main__':
141  main()
142 
143 # --------------------------------------------------------------------------------------------------
144 
fv3jedi_plot_field.main
def main(inputfile, fieldname, layer, showfig)
Definition: fv3jedi_plot_field.py:38
fv3jedi_plot_field.abort
def abort(message)
Definition: fv3jedi_plot_field.py:27