Resource files
What are resource files?
Resource files are ASCII files containing lines of data in which values are assigned to resources. A PyNGL resource file allows you to set PyNGL resources in a manner similar to X11 resources that you set in .Xdefaults or .Xresources files.For example, in the PyNGL tutorial, example 9 has a resource file associated with it called "ngl09p.res" that contains the lines:
*vpXF : 0.05 *cnFillOn : True *mpProjection : StereographicThese resources change the X position of the plot in the viewport, turn contour fill on, and change the map projection to "Stereographic."
There are three levels of resource files: 1) a system resource file, 2) a user resource file, and 3) an individual script resource file. Each one of these, if they exist, are loaded in the order listed, each one overriding any resources set in the previous resource file.
The first resource file loaded, the system resource file, is called "sysresfile" and must reside in the directory echoed by running:
import Ngl print Ngl.pynglpath("sysresfile")This resource file will be loaded every time somebody imports Ngl from that system. If you look at this file, you will see certain resources being set:
- The colormap is set to "rainbow".
- The background and foreground colors are being set to white and black, respectively.
- The global font is being set to "Helvetica".
- The function code is being set to "~".
The second resource file loaded (if it exists) is a user resource file called ".hluresfile" that should reside in a user's home directory. This resource file will be loaded every time that user runs PyNGL, and will be loaded after the system resource file. Thus, if the user sets any of the same resources as the ones in "sysresfile", these resource values will override the ones in "sysresfile". This file is particularly useful if the user doesn't like the defaults set in the "sysresfile".
The third resource file loaded (if it exists), is the individual script resource file. This file needs to have the same name as the name argument to Ngl.open_wks, with a ".res" appended. Any resources set in this file will override resources set in the ".hluresfile" or "sysresfile" files.
Any resources you set in any of these resource files that are misspelled or don't apply to the kind of plots you are creating are ignored. No error messages are printed, so you must be careful to spell the resource names correctly.
Why (or why not) to use resource files
There are many reasons why you may want to use a resource file rather than setting resources directly in your PyNGL script:- They allow you to see all or most of your resources in one
location. You can view your resources easier this way, since they are
not interspersed with other lines in your PyNGL script.
- They may speed up the processing of your PyNGL script, especially
if you have lots of resources. This is because PyNGL can generally
load a resource file faster than it can process resources scattered
throughout a PyNGL script.
- One resource file can apply to many PyNGL scripts, saving you the
task of entering the same resource in multiple PyNGL scripts.
- A resource file that contains the line:
*Font : name_of_font
allows you to change all of the fonts in your plot to a particular font. There is currently no way to change all the fonts in your plot with one line inside a PyNGL script. - Resource files can be used to create stylized plots.
- You may forget that you have a resource file, and spend a lot of
time trying to figure out why your PyNGL script is behaving
differently than you expect.
- Some people prefer to have their PyNGL code and resources in one
place, rather than split between two files.
- If you misspell a resource in the resource file, you don't get an
error message (like you do in a PyNGL script). This makes resource
files difficult to debug.
- If you load other scripts that set resources for you, then these
settings will override any that you set in a resource file.
- Some special resources, like the ngl and
skt cannot be set in a resource file.
How to create resource files
General format
The simplest way to set a resource in a resource file is to start off with an asterisk ("*"), immediately followed by the name of the resource, followed by a colon (":"), followed by the value of the resource. There must be no space between the asterisk and resource name, but you can have as many spaces as you want before and after the colon. Only one resource can be set per line, and comments begin with the "!" character. For example, in the following five lines:
! This is a comment. *tiMainFont : 25 *tiMainString : This is a title *mpFillOn : True *cnLevelSpacingF : 0.10the first line is a comment, and the next four lines set the resources for changing the title font to 25 ("times-roman"), creating a title, turning map fill on, and setting the contour level spacing to 0.10. Note that the string "This is a title" does not require double quotes around it as it would in a PyNGL script. If you put quotes around the string, then the quotes will appear as part of the title.
Resource types
Resources can have four different types: float, integer, string, and logical, and can be scalars or multi-dimensioned arrays.To set a scalar resource, succeed the ":" character with the value of the resource as a float, integer, string, or logical. You've already seen how to do this in the example above:
*tiMainFont : 25 *tiMainString : This is a title *cnLevelSpacingF : 0.10 *mpFillOn : TrueThe first resource is being set with the integer "25", the second resource with the string "This is a title", the third resource with the float "0.10", and the fourth resource with the logical "True".
The number "25" that is being used to set the font is an enumerated
value (an integer that represents a predefined string). When used with
a font resource, the number "25" is an index into a
The processor for resource files expects array syntax compatible with
the underlying legacy code. For example, to set the resource xyExplicitLabels to a 1-dimensional string
array, do the following:
And to set the resource wkColorMap
to a 15 x 3 float array, do the following:
You can force resources in a resource file to only apply to certain
plots by replacing the wildcard asterisk character with "qualifiers".
Whenever you call a PyNGL function that creates a plot, a name is
given internally to that plot (in addition to the function returning a
reference to the plot), and this name can be used as a qualifier in a
resource file. The name given to a plot created by a call to a PyNGL
function is the second string passed to Ngl.open_wks, followed by an underscore
("_"), followed by a string indicating type of plot being created.
For example, if you create a contour plot and a vector plot with the
following calls:
For example, in the following two lines in the resource file for example 9:
You can fully qualify a resource to the point where there are no
wildcard characters. Here's a basic template for what a
fully-qualified resource name would look like in a resource file:
Any place where you don't want to use one of the qualifying names, you
can just replace it with a wildcard character. For example, let's
assume you opened two workstations with the following lines:
The fully qualified path of the above resource would be:
It is important to note that this internal naming scheme of the PyNGL
functions and procedures is somewhat limiting. For example, if you
create two separate contour plots with a call to Ngl.contour and they are both being drawn to
the same workstation, then they will both have the same internal name.
This means that if you want to set the same resource for both of them,
but with different values, you can't do it from a resource file
because there is no way to distinguish the two contour plots from each
other.
*tiMainFont : times-roman
Again, note that there are no quotes around "times-roman". If you had
put quotes around this resource:
*tiMainFont : "times-roman"
then you would have gotten an error message that looks like the
following:
fatal:NhlCvtStringToEnum: Unable to convert string ""times-roman"" to requested type
Logical values can be set with the strings True or
False, or the integers 0 or 1. Both True and
False must be capitalized and must not have quotes around
them.
*xyExplicitLabels: (/curve 1, curve 2, curve 3, curve 4/)
*wkColorMap: (/(/ 0.00, 0.00, 0.00 /),(/ 0.66, 0.66, 0.66 /),\
(/ 0.40, 0.40, 0.40 /),(/ 0.00, 1.00, 1.00 /),\
(/ 0.20, 0.56, 0.80 /),(/ 0.00, 0.00, 1.00 /),\
(/ 0.50, 0.00, 1.00 /),(/ 1.00, 0.00, 1.00 /),\
(/ 0.14, 0.56, 0.14 /),(/ 0.00, 1.00, 0.00 /),\
(/ 1.00, 1.00, 0.00 /),(/ 0.86, 0.58, 0.44 /),\
(/ 0.65, 0.16, 0.16 /),(/ 1.00, 0.50, 0.00 /),\
(/ 1.00, 0.00, 0.00 /)/)
Note: The "\" character is used as a continuation line in a resource
file.
Wildcards
In a resource file, the asterisk in front of the resource name serves
as a wildcard character. In other words, the line:
*cnFillOn : True
causes contour fill to be turned on for all contour plots in an
PyNGL script to which the resource file is applied, unless
cnFillOn is set to False
for a particular contour plot within the PyNGL script. Resources
set in a PyNGL script override resources set in a PyNGL resource
file.
. . .
wks = Ngl.open_wks("x11","myplot")
. . .
contour = Ngl.contour(wks,cdata,cnresources)
vector = Ngl.vector(wks,vdata,vcresources)
. . .
then the function Ngl.contour
assigns the name "myplot_contour" to the contour plot, and the
function Ngl.vector assigns the name
"myplot_vector" to the vector plot. If you call a PyNGL function that
creates two plots, like Ngl.contour_map, then this function assigns
the name "xxx_contour" to the contour plot and "xxx_map"
to the map plot, where xxx is the second string passed to
Ngl.open_wks.
*ngl09n_contour.pmLabelBarDisplayMode : Always
*ngl09n_map.pmLabelBarDisplayMode : Never
the strings "ngl09n_contour" and "ngl09n_map" are internal names
assigned by Ngl.contour_map to the
contour and map plots. These strings are used as qualifiers to force
a label bar to be drawn for the contour plot and not for the map
plot. If you had just set:
*pmLabelBarDisplayMode : Always
then you would have gotten a label bar with both the map plot and
the contour plot.
application_name.workstation_name.plot_name.resource_name : resource_value
In the PyNGL suite of functions, application_name is the second
string passed to Ngl.open_wks and
workstation_name is the same string with "_x11", "_ps", "_pdf", or
"_ncgm" appended, depending on what kind of workstation was opened in
the call to Ngl.open_wks.
xwks = Ngl.open_wks("x11","example")
pswks = Ngl.open_wks("ps","example")
Let's further assume you want to draw a contour plot, but that you
only want to have a title drawn with it in the PostScript
file. Then, you would have an entry in your resource file that looks
like this:
*example_ps*tiMainString : This is a title
The string "example_ps" is the name given to the PostScript
workstation by the call to Ngl.open_wks. Note that a wildcard character
appears between this qualifier and the resource name. This is because
normally the qualifier
plot_name would appear after the workstation name, but since
you don't need it in this case, you can replace it with a wildcard
character.
example.example_ps.example_contour.tiMainString : This is a title
The documentation for the PyNGL functions
contains information about the internal names given to the various
plots, workstations, and data objects.
Where to put individual
resource files
By default, the PyNGL interpreter looks for an individual
resource file in the same directory where PyNGL is being executed.
In the PyNGL suite of functions, if you want to change this
default directory, create an attribute of the second string passed to
Ngl.open_wks called "appUsrDir" and set its value to whatever
directory you want PyNGL to look in for the resource file. For
example, if your PyNGL script is in
"/usr/home/smith/scripts/plotxy.py", and your resource file is in
"/usr/home/smith/resfiles/plotxy.res", then set appUsrDir as follows in the
"/usr/home/smith/scripts/plotxy.py" file:
. . .
resname = "plotxy"
resname.appUsrDir = "/usr/home/smith/resfiles"
wks = Ngl.open_wks("x11",resname)
. . .
Remember, PyNGL looks for a resource file by the name
resname.res, where resname is the second argument (a
string) passed to Ngl.open_wks.