In order to use the PlotManager effectively, it is helpful to understand what is being managed. The PlotManager manages plot objects. What, then, are plot objects?
Plot objectsPlot objects are used to create plots, that is, graphical representations of data accompanied by annotations like labelled tickmarks that give a context to the data and help reveal its meaning. Think of a plot object as an organized collection of View objects that you can draw with a single call. Its focus is a rectangular space within which the data is visualized. This space is called the data coordinate space and is the viewport of a Transform object. By itself, a Transform object is not a plot object, because although it contains a representation of the data, it has no means of placing the data in context. This is where the PlotManager comes in.
You create a basic plot object whenever you instantiate a Transform object with an active PlotManager. Normally, you do not even need to be aware that you are doing this, because, by default, the PlotManager is activated whenever you instantiate one of the composite Transform classes that can be used as a plot object. These include XyPlot, ContourPlot, MapPlot, LogLinPlot, and IrregularPlot.
Role of the PlotManager
The PlotManager operates for the most part behind the scenes. One of its basic roles is to manage the built-in annotations that provide a context for the data. These built-in annotations (known as intrinsic annotations) include titles, tickmarks, a labelbar, and a legend; they are available to any of the plot object classes that choose to use them. The PlotManager does not concern itself with the content of these annotations; its role is limited to turning them on and off, positioning and sizing them relative to the plot object's current viewport, and ensuring that they do not overlap.
The PlotManager provides a number of resources for controlling these attributes. For instance, the resource pmLabelBarDisplayMode determines when the LabelBar should be displayed; and the resource pmLabelBarSide determines the side of the coordinate space viewport on which the LabelBar is to appear. Since the PlotManager is a composite member of the plot object, its resources are set as if they belonged directly to the plot object itself. As an example, to display the LabelBar on the left side of the viewport of a ContourPlot you are creating, you could execute:
C: NhlRLClear(rlist); NhlRLSetString(rlist,"pmLabelBarDisplayMode","always"); NhlRLSetString(rlist,"pmLabelBarSide","left"); NhlCreate(&cnid,"Contour1",NhlcontourPlotClass,wid,rlist); Fortran: call NhlFRLClear(srlist) call NhlFRLSetString(rlist,'pmLabelBarDisplayMode','always',ierr); call NhlFRLSetString(rlist,'pmLabelBarSide','left',ierr); call NhlFCreate(cnid,'Contour1',NhlfcontourPlotClass,wid,rlist,ierr)
Besides managing the built-in annotations, the PlotManager has a number of other capabilities. It allows you to overlay other Transform objects into the data coordinate space of the plot object. It also allows you to add any number of independently-created View objects as external annotations. These overlays and annotations are called "plot members", and they function very much as if they are an integral part of the plot object. Drawing the plot object causes the plot members to be drawn as well; changing the plot object's size or position causes proportional changes to the plot members.
Since an overlay must be a Transform object, it is interesting to note that the overlay might itself be a plot object. Most classes of plot object can perform either role, that of providing the data coordinate space on which Transform objects are overlaid, or that of becoming overlays themselves. A plot object that provides the data coordinate space is called a "base plot object". All plot objects are base plot objects when they are first created. When a plot object becomes an overlay, its PlotManager cedes its management responsibilities to the base plot object's PlotManager. Also note that the base plot determines the boundaries of the coordinate space. If the overlay's data coordinate space extends outside these boundaries, it is clipped.
A common use of overlays would be to render a contour plot of scalar data, such as temperature, projected onto a plot of the region of the earth to which the data values apply. You accomplish this by overlaying a ContourPlot object on a MapPlot object. First you independently create both the ContourPlot and the MapPlot, supplying the appropriate data to the ContourPlot and the appropriate limits and the desired projection to the MapPlot. Then when you execute the following call:
C: NhlAddOverlay(mapplotid,contourplotid,-1); Fortran: call NhlfAddOverlay(mapplotid,contourplotid,-1,ierr)the ContourPlot becomes an overlay of the MapPlot. Essentially, the ContourPlot and the MapPlot are merged into a single plot under control of the MapPlot's PlotManager. The ContourPlot's coordinate space is transformed into the data space of the MapPlot, as defined by one of the ten MapPlot projections and the current projection limits. You can no longer draw the ContourPlot as an independent object, but when you draw the MapPlot the contour data appears properly located within the MapPlot viewport.
If you want to draw the ContourPlot independently again, you must first remove it from the plot on which it is overlaid. This you would do using the NhlRemoveOverlay function.
You can look at the C example mp03c.c or the Fortran example mp03f.f to see a working example of a ContourPlot overlaid on a MapPlot. The command "ng4ex -n mp03c" will deposit the C code in your working directory. Substitute mp03f to get the Fortran code.
You can overlay more than one Transform object on the data coordinate space of a base plot. You could, for instance, display one dataset using filled contours, some related datasets using line contours with distinctive line styles, and, in addition, perhaps locate some important features using markers drawn by XyPlot. All of these components of the final graphic can be drawn on top of each other in a prescribed order controlled by the PlotManager.
If all of the graphical components are line drawings the order in which they are overlaid is not as important as it is when some of the objects are solid filled. For example, contour lines would have to be placed on top of a filled geographic map or they would disappear. Likewise a geographic continental outline would have to be placed on top of a set of filled contours or it would disappear.
The order in which the overlays are drawn is based on the overlay sequence, which you can determine by getting the value of the array resource, pmOverlaySequenceIds. By default, the contents of the base plot are drawn first, followed by each overlay in the order it was added, but you can control the sequence of overlays by manipulating the third parameter of the NhlAddOverlay function. However, the PlotManager also uses a three-phase draw sequence. If the plot object class also supports draw phases, you can gain a greater control over when particular elements of a plot are drawn by manipulating their draw phase. Currently only the ContourPlot and MapPlot have draw phase capabilities.
Managing the location of annotations
The PlotManager uses a scheme based on a series of concentric areas surrounding the plot object's viewport for positioning annotations. Built-in annotations like titles and labelbars, annotations created by plot objects, and external annotations created by the user are all treated alike. Each concentric area is an "annotation zone". Zones are numbered consecutively and except for zones 0 and 1, each zone is shaped like a rectilinear doughnut surrounding the zone preceding it. If no annotation objects are placed in a zone, it will have no area, meaning that its exterior boundary will be coincident with its interior boundary. There is no upper limit to the number of zones used.
The viewport of the plot object, for example, an XyPlot, defines the outer boundary of zone 1. Unlike the outer zones, zone 1 has no "hole" in the middle, because zone 0 is simply a point at the center of the viewport. The boundaries of zone 1 are defined by the viewport resources, vpXF, vpYF, vpWidthF, and vpHeightF, according to:
- vpXF is the left edge of the viewport in NDC space (0.2 default).
- vpYF is the top edge of the viewport in NDC space (0.8 default).
- vpHeightF is the height of the viewport in NDC space (0.6 default).
- vpWidthF is the width of the viewport in NDC space (0.6 default).
In the default case, 40% of the drawable viewspace is available for the outer concentric zones in which titles, legends, labelbars, and other annotations can be placed. In the example below, we put titles for the X and Y Axes into zone 2. Then a main title and a legend are put in zone 3.
------------------------------- | [Zone 3] | |MAIN TITLE EXTENDS TO HERE | | -------------------------| | | Y [Zone 2] | | | | | | A --------------- | | | X | [Zone 1] | | | | I | | | | | S | (X vs Y | | | | | plot here) | | | | T | | | | | I --------------- | | | T X AXIS TITLE EXTENT| | | L | | | E | | -------------------------| | * # @ + | | (Curve legend here) | -------------------------------
The important thing to note about this diagram is that the extent of the annotations occupying a zone determines the area of the zone. In other words the bounding box (the smallest containing rectangle) of the annotations in a zone defines its exterior boundary, as well as the interior boundary of the next higher numbered zone. So, for example, since the X Axis title in zone 2 extends further to the right than the Main Axis title in zone 3, the right boundaries of zones 2 and 3 are colinear, and equal to the right boundary of the bounding box of the X Axis title.
The advantage of this scheme is that you can position annotations without specifying the location in NDC space. Simply by placing annotations in different zones you can ensure that they do not overlap each other. For exact placement relative to the previous zone's boundary, numerical offset resources are available.
Annotation zones are discussed further in the description of the PlotManager Location Control Model.
External annotationsWhen you add an independently-created View object as an annotation to a plot object, the PlotManager creates an AnnoManager object that you use to specify locational and size attributes. The AnnoManager class module discusses how to create and manage external annotations and under what circumstances you might want to make annotations out of independent View objects.
TerminologyThe glossary contains definitions of the terms used to describe the PlotManager's capabilities. The most significant are:
- plot object
- base plot
- plot member
- overlay sequence
- overlay functions
- annotation functions