E3SM VCS Native Grid Plot

This notebook shows how to use VCS to create a plot of data on E3SM's native grid.

To download this Jupyter Notebook, right click on the link and choose "Download Linked File As..." or "Save Link as...". Remember where you saved the downloaded file, which should have an .ipynb extension. (You'll need to launch the Jupyter notebook or JupyterLab instance from the location where you store the notebook file.)

Note: this notebook uses Python 3.

Create Necessary Conda Environment

Prior to running this notebook, create an appropriate conda environment by running the following commands:

conda create -n cdat82mesa-e3sm_nex -c cdat/label/v82 -c conda-forge python=3.6 cdat mesalib

conda activate cdat82mesa-e3sm_nex

Next type the following command to add e3sm_nex to the already-activated cdat81-mesa-e3sm_nex environment:

conda install -c conda-forge -c cdat e3sm_nex

Finally, to run Jupyter Notebooks, add JupyterLab to this environment:

conda install -c conda-forge jupyterlab

Note: for the image below to display correctly, you must use a CDAT v8.2 or later environment.

Start the Jupyter Notebook

To run the notebook, make sure you are in the directory containing the notebook (or in a higher directory where you can navigate down to the notebook) and type:

jupyter-notebook

Load Necessary Modules/Libraries

In [1]:
import e3sm_nex # Library for E3SM NE30 native grid
import cdms2 
import vcs 
import requests 
import numpy
/Users/davis278/miniconda3/envs/cdat82mesa-e3sm_nex/lib/python3.6/site-packages/unidata/__init__.py:2: UserWarning: unidata package is deprecated please use genutil.udunits instead of unidata.udunits
  warnings.warn("unidata package is deprecated please use genutil.udunits instead of unidata.udunits")

Download Data

The data file for this tutorial is "ne30_TS.nc" and the grid file is "ne30np4_latlon.091226.nc".

Both files are downloaded from CDAT's sample data directory in the following lines of code.

In [2]:
def download(fnm):
    r = requests.get("https://cdat.llnl.gov/cdat/sample_data/%s" % fnm,stream=True)
    with open(fnm,"wb") as f:
        for chunk in r.iter_content(chunk_size=1024):
            if chunk:  # filter local_filename, keep new chunks alive
                f.write(chunk)

for filename in ["ne30_TS.nc","ne30np4_latlon.091226.nc"]:
    download(filename)


data_path = "ne30_TS.nc"
grid_file_path = "ne30np4_latlon.091226.nc"

Read Grid Info into Variables for Future Use

The following line reads in the data from the grid file and stores it in the variable gf.

In [3]:
gf = cdms2.open(grid_file_path)

We need to work with a complete dataset so the next lines of code takes the latitude, longitude and element corners from the grid file, fills them out and loads them into the variables lats, lons, and ec, respectively.

In [4]:
lats = gf("lat").filled()
lons = gf("lon").filled()
ec = gf("element_corners").filled()

Double checking the contents of the different variables:

In [5]:
gf
Out[5]:
<CDMS file '/Users/davis278/repos/Animations/E3SM_Grids_v2_LATEST/ne30np4_latlon.091226.nc', mode 'r' at 11b3d47b0, status: open>
In [6]:
lats
Out[6]:
array([-35.26438968, -35.65057146, -36.25571591, ...,  36.67639288,
        36.67639288,  36.04994306])
In [7]:
lons
Out[7]:
array([315.        , 315.82917961, 317.17082039, ..., 133.65688686,
       136.34311314, 135.        ])
In [8]:
ec
Out[8]:
array([[    1,     2,     3, ..., 48598, 48601, 48602],
       [    5,     6,     7, ..., 24400, 24399, 24398],
       [    6,     7,     8, ..., 24399, 24398, 16471],
       [    2,     3,     4, ..., 48601, 48602, 16470]], dtype=int32)

Generate the ne30 Grid

The next line generates the ne30 grid using the filled out lats, lons and ec variables.

In [9]:
grid = e3sm_nex.generateNEXGrid(lats, lons, ec)

Double checking that the grid was created.

In [10]:
grid
Out[10]:
<TransientGenericGrid, id: grid_1, shape: (48602,)>

Load Data and Apply Grid

The first line below opens the data file, "ne30_TS.nc", and assigns it to the variable fd (for "file, data" as opposed to "file, grid").

The second line takes the radiative surface temperature data (TS) from the netCDF data file (fd) and loads it into the data variable.

In [11]:
fd = cdms2.open(data_path)
data = fd("TS")

Double checking that the data was loaded into the data variable:

In [12]:
data
Out[12]:
TS
masked_array(
  data=[[293.04092, 292.6708 , 291.9738 , ..., 289.3111 , 287.35007,
         289.5427 ],
        [292.685  , 292.32184, 291.6398 , ..., 289.4365 , 287.02417,
         289.0147 ],
        [292.57162, 292.22723, 291.54614, ..., 289.50833, 286.75452,
         288.88892]],
  mask=False,
  fill_value=1e+20,
  dtype=float32)

The next line applies the native ne30 grid to the data.

In [13]:
data = e3sm_nex.applyGrid(data,grid)

Plot the Gridded Data

Create the canvas and call it x. Set the canvas size to 2400 pixels by 1600 pixels.

In [14]:
x=vcs.init(bg=True, geometry=(2400,1600))

Create the graphics method variable mesh:

In [15]:
mesh = vcs.createmeshfill()

The following lines of code allow you to display a sub-section or sub-domain of the globe. By using -180 to 180 for the x-direction (longitude) and -90 to 90 for the y-direction (latitude), we'll display the whole globe.

In [16]:
mesh.datawc_x1 = -180
mesh.datawc_x2 = 180
mesh.datawc_y1 = -90
mesh.datawc_y2 = 90

If you want to display the mesh on the globe, set mesh.mesh = True. For this plot we will not display the mesh, but it is displayed in the second plot below.

In [17]:
#mesh.mesh = True

Define the projection, p, for the plot. Here we'll use the Orthographic projection with a center longitude of 30 degrees and a center latitude of 45 degrees.

The last line of code assigns this projection, p, to the mesh.projection attribute.

In [18]:
p=vcs.createprojection()
p.type="orthographic"
p.centerlongitude=30.
p.centerlatitude=45.
mesh.projection=p

Finally, plot the data which has been already scaled to E3SM's native grid.

In [19]:
x.plot(data, mesh, ratio="autot")
Out[19]:
<vcs.displayplot.Dp at 0x11bea6e18>

Save the image above as a .png file titled "NE30_orthographic.png" to make it easier to zoom in on the image.

In [20]:
x.png("NE30_orthographic")

Open the .png file and display on the computer's screen.

In [21]:
!open NE30_orthographic.png

Plot with Mesh Showing

To display the mesh on the plot, set mesh.mesh = True.

In [22]:
mesh.mesh = True

Clear the VCS canvas, x, before creating the plot; then create the plot.

In [23]:
x.clear()
x.plot(data, mesh, ratio="autot")
Out[23]:
<vcs.displayplot.Dp at 0x11bea6ee8>

Save the image above as a .png file titled "NE30_orthographic_w_mesh.png" to zoom in to see more details.

In [24]:
x.png("NE30_orthographic_w_mesh")

Open the .png file and display on the computer's screen.

In [25]:
!open NE30_orthographic_w_mesh.png

Switch Projections

First let's check the existing projection to make sure everything is as it should be with the orthographic projection. Use p.list to list the details of the projection, p.

In [26]:
p.list()
---------- Projection (Proj) member (attribute) listings ----------
secondary method = Proj
name = __projection_182127030786670
type = orthographic
sphere = 1e+20
centerlongitude = 30.0
centerlatitude = 45.0
falseeasting = 1e+20
falsenorthing = 1e+20

Now let's see what other default projections VCS provides. The following line of code lists VCS's default projections.

In [27]:
vcs.listelements('projection')
Out[27]:
['__projection_182127030786670',
 'default',
 'lambert',
 'linear',
 'mercator',
 'mollweide',
 'orthographic',
 'polar',
 'polyconic',
 'robinson']

For comparison, let's switch to the Lambert projection with the default settings, and set the mesh's projection to this new Lambert projection.

In [28]:
p=vcs.createprojection()
p.type="lambert"
mesh.projection=p

For this plot, let's turn off the mesh.

In [29]:
mesh.mesh = False

Clear the canvas and create the Lambert plot.

In [30]:
x.clear()
x.plot(data, mesh, ratio="autot")
Out[30]:
<vcs.displayplot.Dp at 0x11c076048>

Save the image above as a .png file titled "NE30_Lambert.png", again to enable zooming in to see more details, then display the file on the computer screen.

In [31]:
x.png("NE30_Lambert")
!open NE30_Lambert.png

Now let's turn the mesh back on for this new projection.

In [32]:
mesh.mesh = True

Clear the canvas again and plot the data.

In [33]:
x.clear()
x.plot(data, mesh, ratio="autot")
Out[33]:
<vcs.displayplot.Dp at 0x11c076118>

Save this image as a .png to enable zooming and open the .png to inspect it.

In [34]:
x.png("NE30_Lambert_w_mesh")
!open NE30_Lambert_w_mesh.png

In both the orthographic and the Lambert projections, you can see the corners of the E3SM native grid as well as the non-standard grid cell size, though both features are easier to visualize using the orthographic projection.

The CDAT software was developed by LLNL. The initial material for this tutorial was written by Charles Doutriaux. Updates and additional code/plots were added by Holly Davis on December 18, 2019. This work was performed under the auspices of the U.S. Department of Energy by Lawrence Livermore National Laboratory under Contract DE-AC52-07NA27344.

If you have questions about this notebook, please email our CDAT Support address, cdat-support@llnl.gov.