The hints and tips listed below assume you have some basic knowledge of NCL, and know how to create plots using NCL.
Note: most or all of the NCL scripts mentioned in this FAQ do not use the GSUN functions or procedures. These questions are designed to be useful for general NCL users. The NCL scripts and resource files that are referenced by name in the questions below can be downloaded by clicking on the name, and they are also listed in the appendix for your convenience.
When you create an NcgmWorkstation, set the resource wkMetaName to whatever name you want for your metafile (enclosed in double quotes). When you create a PSWorkstation, set the resource wkPSFileName to whatever name you want for your Postscript file. Here's an example of changing the NCGM file name to "plot.ncgm":
begin ; ; Create an NCGM Workstation and change the name of the metafile to ; "plot.ncgm." ; wks = create "wks" ncgmWorkstationClass defaultapp "wkMetaName" : "plot.ncgm" end create mapid = create "map" mapPlotClass wks end create ; Create a map object. draw(mapid) ; Draw the map plot. frame(wks) ; Advance the frame. end
How do I set up my NCL script so that it uses a resource file?
You need to create an App (Application) object before you create a Workstation object, and then use this object as the parent of any objects that originally had "defaultapp" as their parent. Whatever name you give the App object, the NCL script will look for a resource file called name.res. For example, if you have the following NCL script:
begin ; Create an App object. appid = create "title_app" appClass defaultapp end create ; Create an X Workstation object. wid = create "example" xWorkstationClass appid end create ; Create a Title object. tid = create "title" titleClass wid end create draw(tid) ; Draw the title. frame(wid) ; Advance the frame. endthen it will look for a resource file called "title_app.res". The above NCL script alone won't produce any output, but if you have the following lines in your "title_app.res" file:
*tiMainString : Hello, World *tiMainFontColor : 2 *tiMainFont : helvetica-bold *tiMainFontHeightF : 0.06then you should see a red "Hello, World" string at the top of the frame.
How do I change all of my fonts to be the same font?
First set up your NCL script to use a resource file (see the question on resource files above), and then in this file include the following line:
*Font : helveticato change all fonts to helvetica (use whatever font you want, of course). Any fonts that you are explicitly setting in your NCL script will override this resource file setting.
For an example, see the script "font.ncl," along with its resource file "font.res" and its output. Try changing "times-bold" in the "font.res" file to other fonts to see the results. Use either a font name or a font index as listed in the font table at:
http://ngwww.ucar.edu/ngdoc/ng/ref/FontTable.htmlIf you always want to use this font in all of your NCL scripts, then put the above line in a file called ".hluresfile" in your home directory. For more information about resources files, see the section "Using resource files" in the NCAR Graphics User Guide.
How do I get the current date in NCL?
Use the systemfunc function, which executes a system call and returns the output as a string:
datestr = systemfunc("date")
How do I determine the dimensions of an array?
Use the function dimsizes which returns the dimension sizes as a 1-dimensional array. For example, if your array was set with:
x = (/(/(/5,2/), (/2,3/), (/4,4/)/), (/(/0,8/), (/5,1/), (/3,6/)/), \ (/(/9,9/), (/3,0/), (/5,7/)/), (/(/2,1/), (/4,7/), (/1,6/)/)/)then use the following code:
y = dimsizes(x)to retrieve the dimension sizes of x. In the example above, y will be equal to (/4, 3, 2/).
How do I retrieve an environment variable in NCL?
Use the function getenv:
env_str = getenv("PATH")
My text strings either have garbage in them or they are not getting fully displayed. What's the problem?
If you are also getting error messages that look like this:
PLCHHQ - CHARACTER NUMBER 10 (w) IS NOT A LEGAL FUNCTION CODEthen most likely the problem is that you have a colon character (":") in your string. By default, if NCL sees a colon in your string, it's expecting the next character to be a special "function code."
To get around this, you need to tell NCL that you don't want the colon character to represent the start of a function code. To change the special colon character to another character, use any one of the *FuncCode resources that corresponds with the resource you are using to set the text string. For example, if you are setting the string with the txString resource:
"txString" : "Time : 0600 hours"then change the function code to another character (say "~") with the txFuncCode resource:
"txFuncCode" : "~" "txString" : "Time : 0600 hours"If you are setting the string for the X axis label (tiXAxisString), then the corresponding function code resource would be tiXAxisFuncCode, and so on. There are many other string resources that have a corresponding function code resource. There is currently no way to change them all with one call, but here's the list of all of them for your reference:
cnConstFLabelFuncCode stZeroFLabelFuncCode cnHighLabelFuncCode tiMainFuncCode cnInfoLabelFuncCode tiXAxisFuncCode cnLineLabelFuncCode tiYAxisFuncCode cnLowLabelFuncCode tmXBLabelFuncCode gsLineLabelFuncCode tmXTLabelFuncCode gsTextFuncCode tmYLLabelFuncCode lbLabelFuncCode tmYRLabelFuncCode lbTitleFuncCode txFuncCode lgLabelFuncCode vcMinAnnoFuncCode lgLineLabelFuncCode vcRefAnnoFuncCode lgTitleFuncCode vcZeroFLabelFuncCodeOn our list of enhancements we'd like to make to NCL is to make it so that you can set all of these function code resources with one line like you do for fonts (mentioned in a previous question):
*FuncCode : ~
How do I generate a 1-dimensional array of equally-spaced integers or floats?
Use the function ispan to generate integers and fspan to generate floats. For example, to generate the list of integers (9, 12, 15, ..., 96, 99) you would use:
iarray = ispan(9,99,3)To generate 20 equally-spaced floating point numbers between 0.0 and 50.0 you would use:
farray = fspan(0.0,50.0,20)
If I am running NCL interactively, are there any command-line shortcuts I can use?
Yes, there are. These shortcuts allow you to navigate through previous commands and edit them. For more information, go to:
How do I call a C or Fortran function or procedure from NCL?
Use an application called wrapit77. For more information about wrapit77 and some examples on how to use it, go to:
How do I print nicely formatted, multiple columns of data in NCL?
The best way to do this is to write a C or Fortran subroutine to print the data as you want it, and then use wrapit77 as described in the answer to the question about how to call a C or Fortran function or procedure from NCL. There's an example on 2-dimensional array printing in the "Going beyond the basics" chapter.
How do I get multiple plots on a page?
If your plots are all the same size, then you can use the GSUN procedure gsn_panel that takes as input the workstation you want to draw the plots on, the list of plots you want to put on one page, an array describing the layout of the plots, and an optional list of resources. For an example of using gsn_panel, see the script "panel.ncl" and its output (frame 1 and frame 2).
Or, if you are using straight NCL code, then for each plot you create, change the viewport resources vpXF, vpYF, vpWidthF, and vpHeightF to indicate where you want each plot drawn and how big you want each plot to be. Remember, the viewport coordinates are normalized; that is, they go from 0.0 to 1.0 (inclusive). For an example of drawing four plots on one page, see the NCL script "multiple.ncl" and its output.
What's a good way to generate a color map?
First see the section "Creating your own color map using HSV values" for an introduction to the HSV color wheel and how it helps you create a color map. Then, try modifying the file "color.ncl" and running it through NCL to see the different results you get by modifying the HSV values (you'll also need to download "hsv2rgb.ncl").
How do I set color resources by color name rather than color index values?
Any place that you would normally use a color index value, you can also use a color name enclosed in double quotes. (A list of the valid color names is in the file "$NCARG_ROOT/lib/ncarg/database/rgb.txt.") For example, if color index 2 is red in your color map, and you want to set the main title font color to red, then you can do it one of two ways from an NCL script:
Using a color index value:
... "tiMainFontColor" : 2 ...Using a color name:
... "tiMainFontColor" : "red" ...Whenever a named color is used, the current color map is searched for the color that is the closest match to that color. This means that if you access a color that doesn't have a close match in your color map, you may not get the color you are expecting. To get around this problem, make sure the color map you use contains all the named colors you want by adding them explicitly to your color map.
For example, if you want your general color map to have the following RGB values:
(/(/0.0,0.0,0.0/),(/1.0,1.0,1.0/),(/1.0,0.0,0.0/),(/0.0,1.0,0.0/), (/0.0,0.0,1.0/),(/1.0,1.0,0.0/),(/0.0,1.0,1.0/),(/1.0,0.0,1.0/), (/0.5,0.0,0.0/),(/0.5,1.0,1.0/),(/0.0,0.0,0.5/),(/1.0,1.0,0.5/), (/0.5,0.0,1.0/),(/1.0,0.5,0.0/),(/0.0,0.5,1.0/),(/0.5,1.0,0.0/), (/0.5,0.0,0.5/)/)and you also want to use the named colors "Olive", "Plum", "Gold", "MediumBlue", and "LightSlateGray", then set the color map resource wkColorMap as follows:
... "wkColorMap" : (/"(/0.0,0.0,0.0/)","(/1.0,1.0,1.0/)","(/1.0,0.0,0.0/)",\ "(/0.0,1.0,0.0/)","(/0.0,0.0,1.0/)","(/1.0,1.0,0.0/)",\ "(/0.0,1.0,1.0/)","(/1.0,0.0,1.0/)","(/0.5,0.0,0.0/)",\ "(/0.5,1.0,1.0/)","(/0.0,0.0,0.5/)","(/1.0,1.0,0.5/)",\ "(/0.5,0.0,1.0/)","(/1.0,0.5,0.0/)","(/0.0,0.5,1.0/)",\ "(/0.5,1.0,0.0/)","(/0.5,0.0,0.5/)",\ "Olive","Plum","Gold","MediumBlue","LightSlateGray"/) ...Note: in order to mix RGB values with color names, you must enclose each entry in double quotes. More information about named colors is available in the "Creating your own color map using named colors and RGB values" section of the "Basics" chapter.
How do I get my PostScript output to cover most of an 8-1/2" x 11" page?
When you create your PostScript workstation, use the resources wkDeviceLowerX, wkDeviceLowerY, wkDeviceUpperX, and wkDeviceUpperY to position the PostScript output anywhere on the page.
For an example, see the "ps.ncl" script and its PostScript output. Note that it is possible to have negative values for these resources.
For a landscape-oriented example, see the Quick Start Guide example "cn15."
To open any one of these types of files, use the addfile function, which opens a data file and returns a pointer to the file. Once you have a pointer to the file, you have access to all of its global and variable attributes and coordinate arrays. You also use addfile to open a netCDF or HDF file for writing (not GRIB or CCM files, since you can't write these files in NCL). For a simple example, see the script "readnc.ncl" and its output.
For more complex examples on NCL file I/O, go to:
How do I read/write ASCII files?
Use the asciiread function to read an ASCII file and the asciiwrite procedure to write an ASCII file. For a simple example, see the script "readasc.ncl."
For a more complex example, go to:
How do I read/write binary files?
Use one or more of the functions cbinread, cbinwrite, craybinrecread, fbindirread, fbindirwrite, fbinread, fbinrecread, fbinrecwrite, and fbinwrite, depending on what type of binary file you have. In addition, you may also want to use the functions craybinnumrec or fbinnumrec for getting the number of unformatted Fortran records in a file.
For some complex examples, go to:
Once I've opened a file with addfile, how can I find out what variables and attributes it contains?
Use the functions getfilevaratts, getfilevardims, and getfilevarnames to retrieve the list of attribute names for a file variable, the list of dimension names for a file variable, or the list of variable names for a file, respectively.
For the variable that contains your data, set the attribute "_FillValue" to the missing value. For example, the following NCL code:
x = (/1,2,3,-999,5,6,7,-999,-999,10/) x@_FillValue = -999sets the missing value of x to "-999".
The "_FillValue" attribute is recognized by many NCL functions and procedures and thus the computations will behave differently when they encounter missing values (like ignore them or return with an error message). For example, if you pass the above x array to the NCL function sum, you will get a return value of 34.
How do I determine if my data contains any missing values?
Use the function ismissing which returns a logical array with the same dimensions as your data, with the values set to True or False depending on whether the value at that location is a missing value.
If you just want to find out if any of your data values are missing, but you don't care which ones, then you can do something like:
i = any(ismissing(data)))and i will be set to True of any of data's values are equal to data@_FillValue and False otherwise.
How do I find the minimum/maximum values of my data array?
Use the functions min and max. For example, in the following NCL code where x is a 4 x 2 array, xmin will be equal to -3 and xmax will be equal to 8:
x = (/(/-1,3/), (/0,5/), (/1,-2/), (/-3,8/)/) xmin = min(x) xmax = max(x)
How do I average all the values in a multi-dimensioned array?
Use the function avg. For example, in the following NCL code snippet where x is a 2 x 3 x 2 array, y will be a scalar value equal to 2.916667:
x = (/(/(/2,3/), (/4,5/), (/1,2/)/), (/(/3,8/), (/1,4/), (/0,2/)/)/) y = avg(x)If you want to average all the values in a multi-dimensioned array for a particular dimension, then use the dim_avg function. For example, if you have a 3-dimensional array called temp that contains temperature values on a latitude/longitude grid for each hour of the day, and you want to compute the average temperature at each hour, then your code would look something like this:
temp!0 = "time" temp!1 = "lat" temp!2 = "lon" hourly_avg_temp = dim_avg(temp(lat|:,lon|:,time|:))The above example also shows how to reorder your dimensions in case the dimension that you want to average across is not the last dimension of your array. hourly_avg_temp will be a 1-dimensional array with the same number of elements as the first dimension of temp.
How do I interpolate my 2-dimensional random data to a 2-dimensional gridded array?
Use the Natgrid function natgrids or the Dsgrid function dsgrid2s. For a simple example, see the script "2dgrid.ncl." For some more complex examples, see the Quick Start Guide examples "nm01," "nm02," "nm03," "nm05," and "nm06."
How do I interpolate my 3-dimensional random data to a 3-dimensional gridded array?
Use the Dsgrid function dsgrid3s. For a simple example, see the script "3dgrid.ncl." For a more complex example, see the Quick Start Guide example "nm04."
For contour data, use the ScalarField resource sfMissingValue. For an example, see "misscon.ncl" and its output. Note the hole in the middle of the contour plot due to the presence of missing values.
For XY data, use the resource caXMissingV or caYMissingV, depending on where you want to indicate missing values. For an example, see "missxy.ncl" and its output.
How do I get log scaling in an XY or contour plot?
For an XY plot, set the LogLinTransformation resources trXLog and/or trYLog to True, depending on which axes you want to be in log scaling. For an example see the script "logxy.ncl" and its output (frame 1 with default linear/linear scaling and frame 2 with linear/log scaling).
For a contour plot, the method for changing to log scaling depends on whether the coordinates for the axis you want to log are regularly or irregularly spaced. If they are regularly spaced, then use trXLog or trYLog just like it was done for the XY plot above. For an example, see the script "logcon1.ncl" and its output (frame 1 with default linear/linear scaling and frame 2 with linear/log scaling).
If the coordinates for the axis you want to log are irregularly spaced (as they are if you set either the sfXArray or sfYArray resource), then you need to create a LogLinPlot object, specify which axis is to be logged, overlay the ContourPlot object on this LogLinPlot object, and then draw it. For an example, see the script "logcon2.ncl" and its output (frame 1 with default linear/linear scaling and frame 2 with linear/log scaling).
For a more advanced example, see the Quick Start Guide example "xy09."
How do I fill my contour levels with various shading patterns and/or solid colors?
If you just want to fill your contour levels with various solid colors, set cnFillOn to True. To change the default colors used for the contour levels, set cnFillColors to an array of desired color indexes (be sure to include enough colors for the number of contour levels plus one).
If you want to fill the contour levels with different shading patterns, you must set cnMonoFillPattern to False. To change the default fill patterns used for the contour levels, set cnFillPatterns to an array of desired fill pattern indexes (again, make sure you include enough fill pattern indexes for the number of contour levels plus one). There are 18 different fill patterns: pattern 0 is solid fill, patterns 1-16 are various fill patterns, and pattern 17 is a special stipple fill pattern. If you use "-1" for a fill pattern, this means to leave it transparent (no fill).
For an example showing how to create a contour plot using different fill patterns and colors, see the script "fillcon.ncl" and its output.
I've created an XY plot and am trying to change some attributes of the curves (like the line color or thickness), but nothing is happening!
When you create an XyPlot object, you cannot set resources for changing attributes of the curves (like their color, thickness, labels, and dash patterns) at the same time. You need to 1) create the XyPlot object, 2) retrieve the value of the resource xyCoordDataSpec with a call to getvalues, and 3) set the desired resources by calling setvalues on the resource you just retrieved and passing the list of resources you want to set. For an example, see the script "xyplot1.ncl" and its output.
An XyPlot object can have multiple data objects (unlike a ContourPlot, VectorPlot, or StreamlinePlot object). If this is the case, and you retrieve xyCoordDataSpec, then you will get an array of values, one for each data object created. For an example of how to deal with an array of DataSpec objects (as they are called) and changing attributes for multiple curves, see the script "xyplot2.ncl" and its output.
How do I overlay a contour plot (or a vector/streamline plot) on a map?
There are two ways to do this. If the contour plot has not already been transformed to map coordinates, then use the four ScalarField resources sfXCStartV, sfXCEndV, sfYCStartV, and sfYCEndV to indicate where you want the contour plot to lie on the map plot, and then use the overlay function to overlay the contour plot on the map plot. See the NCL script "overlay1.ncl" and its output for an example. Note that the contour plot only covers the latitude area from -45 to 45, and the longitude area from -90 to 90 (because these are the limits specified in the script).
If the contour plot has already been transformed to map coordinates, then all you need to do is create a map plot object and a contour plot object, make sure they are both drawn in the same viewport location (using the resources vpXF, vpYF, vpWidthF, and vpHeightF), and then draw them both. For an example, see the script "overlay2.ncl" and its output. Note that in this second example, the contour plot covers the full map plot.
The same method used for overlaying a contour plot on a map plot is used for overlaying a vector or streamline plot on a map, with some of the resource names changed. For examples, see "vector.ncl" and "stream.ncl."
For some more complex examples, see the Quick Start Guide examples "cn12," "cn14," "cn15," "cn16," "vc06," "vc07," "vc08," "vc09," and the GSUN examples 5, 6, and 9.
I've got multiple contour plots on one page and want to create one labelbar that represents all of them. How do I do this?
Normally, when you create a ContourPlot object, you set the PlotManager resource pmLabelBarDisplayMode to True to get a labelbar. However, when you are dealing with multiple plots on one page, it is easier to create your own LabelBar object, because this way you have more control over where to put it, how you want to label it, etc.
For an example of four contour plots on one page with a labelbar, see the script labelbar.ncl and its output.
How do I label the latitude/longitude grid in my map?
If your projection is rectangular, then create a TickMark object and use the resources tmXBMode, tmXBValues, tmXBLabels, tmYLMode, tmYLValues, and tmYLLabels to label the axes anyway you like. For an example, see "map1.ncl" and its output.
If your projection is elliptical, then you need to use a different method than creating a TickMark object. Instead, you need to create a TextItem object for each latitude/longitude label that you want to draw, figure out where in the viewport you want to draw each label, and draw them. For an example, see "map2.ncl" and its output.
For some more complex examples, see the Quick Start Guide examples "cn14," "cn15," and "cn16."
How do I get multiple scales on my XY or contour plot?
There are two ways you to do this. One way is to set one of the tm*Mode resources to Explicit (depending on which axis you want to label separately) and then use tm*Values and tm*Labels resources to get the labels that you want at whatever tick mark values you want them. For an example, see "scale1.ncl" and its output.
Another way is to create separate TickMark object for the other scales you want to create, and just draw them on top of each other. For an example, see "scale2.ncl" and its output.
For an example of different scales on a contour plot, see the script "scale3.ncl" and its output. For some more complex examples, see the Quick Start Guide example "xy16" and the GSUN example 11.
How do I generate a wire-frame surface plot in NCL?
There's a routine called tdez2d that provides an interface between NCL and Tdpack, a package of 3-dimensional plotting routines that is currently only implemented at the subroutine library level.
For a simple example of how to use tdez2d, see the script tdez2d.ncl and its output. For more complex examples, see the Quick Start Guide examples "nm05," "nm06," and "nm12."
How do I generate a 3-dimensional plot in NCL?
There's a routine called tdez3d that provides an interface between NCL and Tdpack, a package of 3-dimensional plotting routines that is currently only implemented at the subroutine library level.
For a simple example of how to use tdez3d, see the script tdez3d.ncl and its output. For a more complex example, see the Quick Start Guide example "nm04."
Download a script called ncgm2gif from the URL:
http://ngwww.ucar.edu/info/ncgm2gifwhich allows you convert single frame NCGMs to single frame GIFs, or multi-frame NCGMs to an animation GIF. For example, if your metafile is called "example.ncgm," then convert it to a GIF file with the command:
ncgm2gif example.ncgmThis will create a GIF file called "example.gif."
This script requires that you have the NCAR Graphics commands ctrans and ncgmstat on your system. Also, you must have the public domain application, Image Tools, available via the URL:
ftp://ftp.sdsc.edu/pub/sdsc/graphics/imtools/and gifmerge (only needed if you want to create animation GIFS), available via the URL:
How do I convert my multi-frame NCGM file to an MPEG file to put on the web?
Download a script called ncgm2mpeg from the URL:
http://ngwww.ucar.edu/info/ncgm2mpegand then run:
ncgm2mpeg example.ncgmto create an mpeg file called "example.mpg".
This script requires that you have the NCAR Graphics commands ctrans, rassplit, and ncgmstat on your system. Also, you must have the public domain applications ppm2cyuv, rasttopnm, and mpeg available from the following respective URLs:
Go to the URL:
http://ngwww.ucar.edu/ngdoc/ng/ref/hlu/HluClasses.htmlThis shows a list of every single object in NCAR Graphics. Note that not all of these objects are user-creatable. It is specified for each object whether it can be created by the user.
Where can I see a list of all the NCL resources?
Go to the URL:
Where can I see a list of all the NCL functions and procedures?
Go to the URL:
Where can I see some examples of how to use NCL?
The Quick Start Guide contains several examples, most of which are available in C, Fortran, and NCL. For a pictorial guide, go to:
http://ngwww.ucar.edu/ngdoc/ng/qsg/pickutil.htmland click on type of the plot you want to create. Several examples will be displayed, so click on the one that's closest to what you want to create, and a short description of that example will come up.
For a table of all the available examples along with a one line description of what each one does, go to:
http://ngwww.ucar.edu/ngdoc/ng/qsg/exampletable.htmlThere's also a set of examples that are part of this "Getting started using NCL" document. These examples use a set of functions and procedures that simplify the interface for creating graphics in NCL. For a list of the examples along with a detailed description of each one, go to the "Learning NCL by example" chapter.