About Chandra Archive Proposer Instruments & Calibration Newsletters Data Analysis HelpDesk Calibration Database NASA Archives & Centers Chandra Science Links

Skip the navigation links
Last modified: 9 July 2009

URL: http://cxc.harvard.edu/chips4.1/gallery/axes_add.sl.html

Gallery: Adding axes (S-Lang)

Examples


Using a line to indicate an axis

Extra axes can be added to a plot using the add_axis command, as will be shown in later examples. However, often all that is needed is a line, as used in this plot.

[ChIPS output]
Postscript version
add_curve("atan.fits[cols X,Y]",{"symbol.style","none"});

add_hline(0.0);

The simplest way to add an axis to a plot is to use add_hline or add_vline to draw a horizontal or vertical line, respectively. In this example add_hline is used to draw a line at y=0; this line will always extend across the whole plot, whatever the X-axis range is.

The settings for the current line can be found by using the get_line routine:

chips> get_line;
color = default
depth = 100
extend = 3
id = None
stem = None
style = 1
thickness = 1.0

Adding an extra axis to a plot [Updated]

In this example we create an actual axis, along with tick marks and labels, to indicate the y=0 position. Since it is a duplicate of the original axis, at the bottom of the plot, we bind together the axes so that they cover the same range. The following examples (A single plot containing two datasets with a common axis and Two y axes on the left of the plot) show how an extra axis can be used to create a new coordinate system, allowing different data to be added to the same plot.

[ChIPS output]
Postscript version
add_curve("atan.fits[cols X,Y]",{"symbol.style","none"});

add_axis(X_AXIS,0.0,1.0,10.0,{"coordsys",DATA});
bind_axes("ax1","ax2");

% Set the tick marks on the new axis to extend to both sides
variable axis = ChipsAxis;
axis.majortick.style = "centered";
axis.minortick.style = "centered";
axis.majortick.length = 10;
axis.minortick.length = 6;
axis.ticklabel.visible = 0;
set_axis("ax2",axis);

After creating the plot with add_curve, we add a second X axis at y=0 using add_axis. The first argument (X_AXIS) defines the axis type, the second argument the position (y=0), and the remaining arguments the initial range for this axis; in this example it doesn't matter what values we use, as explained below, so we pick 1 to 10 as they are easy to type.

The bind_axes call is used to make the new axis (which has been given the name ax2, as shown below in the info output) automatically mirror the original X axis range and scaling. After this call, a change to the scaling or limits of one axis will automatically be applied to the other.

Finally we adjust the length and placement of the tickmarks using the set_axis command, in order to extend to both sides of the axis (the default behavior is to just extend in one direction, as seen on the bottom and left-hand axes).

The info, info_current, info_coordinate and info_bound_axes commands provide information about the existing ChIPS objects; after creating the above plot the output of these commands looks like:

chips> print(info);
Window [win1]
  Frame [frm1]
    Plot [plot1]   (0.20,0.20)  .. (0.90,0.90)
      Border bottom [bx1]  top [bx2]  left [by1]  right [by2]
      X Axis [ax1]
      Y Axis [ay1]
      Curve [crv1]
      X Axis [ax2]

chips> print(info_current);
Window [win1]
  Frame [frm1]
    Plot [plot1]
      Y Axis [ay1]
      Curve [crv1]
      X Axis [ax2]
    Coord Sys [Data]
    Coord Sys ID [plot1_ax2ay1]

chips> print(info_coordinate);
Window [win1]
  Frame [frm1]
    Plot [plot1]
        Coord Sys ID [plot1_ax1ay1]
        X Axis [ax1]
        Y Axis [ay1]
        Coord Sys ID [plot1_ax2ay1]
        X Axis [ax2]
        Y Axis [ay1]

chips> print(info_bound_axes);
Window [win1]
  Frame [frm1]
    plot1:bx1   ->   plot1:bx2
    plot1:by1   ->   plot1:by2
    plot1:ax1   ->   plot1:bx2
    plot1:ay1   ->   plot1:by2
    plot1:ax1   ->   plot1:ax2

Changes in CIAO 4.1

  • Axes now always default to using the plot-normalized coordinate system for placement, whereas in CIAO 4.0 the current coordinate system was used. This is most noticeable for axes added to existing plots, where the old behavior would have been to place the axis using the existing data coordinate system.

    In this plot, since the y=0 axis is being added to a plot with existing axes, the CIAO 4.0 version

    add_axis(X_AXIS, 0, 1, 10);
    

    would not apear to work in CIAO 4.1, since the new axis lies on top of the old one (as y=0 in plot-normalized coordinates refers to the bottom of the plot). We therefore need to explicitly state that the current data coordinate system should be used, by setting the coordsys attribute:

    add_axis(X_AXIS, 0, 1, 10, {"coordsys", DATA});
    
  • The coordinate system to be used when placing an object can now be declared in the attribute list, using the attribute name "coordsys", whereas previously you had to create a ChipsId object and set its coord_sys field. So

    variable cid = ChipsId;
    cid.coord_sys = PLOT_NORM;
    add_label (cid, 1.05, 0.5, "\Delta \alpha (deg)"R);
    

    can now be written

    add_label (1.05, 0.5, "\Delta \alpha (deg)"R, {"coordsys", PLOT_NORM});
    
  • The axis ticklabel.visible attribute can now be set using add_axis, set_axis, and in the ChipsAxis structure. It is therefore no longer necessary to use the low-level set_axis_ticklabel_visible() routine to change this attribute.


A single plot containing two datasets with a common axis [Updated]

In this plot we want to display two sets of data with the same X axis (in this case time) but different Y axes (RA and Dec). This could be done using two plots, created using the strip_chart command - examples include Plotting related values in a strip chart and the plots of the Sharing an axis between plots section - but here we decide to use the same plot.

Since we have two different coordinate systems - (time,RA) and (time,Dec) - we need two Y axes; in this example we place the second axis on the right-hand side of the plot but it could go anywhere in the frame, as shown in the next example.

[ChIPS output]
Postscript version
set_preference("curve.symbol.style","none");

add_window(6.0,3.0,"inches");

add_curve("aspect.fits[cols time,ra]",{"id","ra"});

set_plot_xlabel("Time (s)");
set_plot_ylabel("RA (degrees)");

% Place the second Y axis at the right-edge of the plot
add_axis(Y_AXIS,1.0,1.0,10.0);

add_curve("aspect.fits[cols time,dec]",{"id","dec","line.color","red"});
limits(Y_AXIS,AUTO,AUTO);

set_plot_ylabel("Dec (degrees)");

set_yaxis({"label.color","red","ticklabel.color","red"});

reposition_plot(0.2,0.2,0.8,0.93);

variable ax = ChipsAxis;
ax.majortick.interval = 1000.0;
ax.tickformat = "%.0f";
ax.offset.perpendicular = 30;
set_xaxis(ax);
variable ay = ChipsAxis;
ay.majortick.interval = 5.0e-3;
ay.tickformat = "%.3f";
ay.minortick.count = 4;
ay.offset.perpendicular = 60;
set_yaxis("ay1",ay);
ay = ChipsAxis;
ay.majortick.interval = 2.0e-3;
ay.tickformat = "%.3f";
ay.minortick.count = 3;
ay.offset.perpendicular = 60;
set_yaxis("ay2",ay);
set_axis("all",{"majortick.mode","interval"});

We start by plotting the first dataset (time,RA) and setting up the axis labels. Note that by setting the id attribute of the curve (here to ra) in the add_curve call, we override the default name (crv1) that would normally be used; we do not actually make use of this name in this example, other than in the output of the various info commands.

We then add a second Y axis to the right-hand edge of the plot (x=1 in plot-normalized coordinates) using the add_axis command. Since we are unsure of the data range that will be used for this axis, we pick a simple range (here 1 to 10) since we can reset it after the data has been added.

At this point - i.e. before the second add_curve call has been made - the output of the info, info_current, and info_coordinate commands looks like the following (note how the curve uses the name we gave, namely ra, rather than the default value of crv1):

chips> info;
Window [win1]
  Frame [frm1]
    Plot [plot1]   (0.15,0.15)  .. (0.90,0.90)
      Border bottom [bx1]  top [bx2]  left [by1]  right [by2]
      X Axis [ax1]
      Y Axis [ay1]
      Curve [ra]
      Y Axis [ay2]

chips> info_current;
Window [win1]
  Frame [frm1]
    Plot [plot1]
      X Axis [ax1]
      Curve [ra]
      Y Axis [ay2]
    Coord Sys [Data]
    Coord Sys ID [plot1_ax1ay2]

chips> info_coordinate;
Window [win1]
  Frame [frm1]
    Plot [plot1]
        Coord Sys ID [plot1_ax1ay1]
        X Axis [ax1]
        Y Axis [ay1]
        Coord Sys ID [plot1_ax1ay2]
        X Axis [ax1]
        Y Axis [ay2]

The current coordinate system is now "plot1_ax1ay2", which means that it is the X axis and the second Y axis. The add_curve call therefore adds the data to this coordinate system, which results in the second Y axis changing to display the new data; the limits call is needed to ensure that just the range of the data is covered in case it is different from the 1 to 10 range the axis was created from (as it is in this case).

Since the second Y axis is current, the limits call does not change the first data set or left-hand axis; similarly the set_plot_ylabel and set_yaxis calls only change the right-hand Y axis. The plot is then re-positioned to ensure the axis labels can be moved further from the axes, so as to avoid overwriting the tick mark labels, without falling off the edge of the frame. The set_xaxis and set_yaxis calls are used to set these label offsets, as well as adjusting the location of the major tick marks. Note that specific axes can be targeted by giving the name of the axis as the first argument of the call - in this case "ay1" and "ay2". The final call uses the special name "all" to refer to all the axes in the current plot; alternatively the "majortick.mode" field of the ChipsAxis structure could have been set to "interval" in each of the preceeding three set_*axis calls.

The final ChIPS object hierarchy looks like the following: note that multiple Y axes are current due to the use of "all" as the identifier in the last set_axis call.

chips> info;
Window [win1]
  Frame [frm1]
    Plot [plot1]   (0.20,0.20)  .. (0.80,0.93)
      Border bottom [bx1]  top [bx2]  left [by1]  right [by2]
      X Axis [ax1]
      Y Axis [ay1]
      Curve [ra]
      Y Axis [ay2]
      Curve [dec]

chips> info_current;
Window [win1]
  Frame [frm1]
    Plot [plot1]
      Y Axis [by1]
      Y Axis [by2]
      X Axis [ax1]
      Y Axis [ay1]
      Y Axis [ay2]
      Curve [dec]

Changes in CIAO 4.1

  • In CIAO 4.0, axes were positioned using the current coordinate system, unless explicitly stated. In CIAO 4.1, axes now always default to using the plot-normalized coordinate system for placement, which means that

    variable cid = ChipsId;
    cid.coord_sys = PLOT_NORM;
    add_axis(cid,Y_AXIS,1.0,1.0,10.0);
    

    can now be simplified to

    add_axis(Y_AXIS,1.0,1.0,10.0);
    

Two y axes on the left of the plot [Updated]

In the previous example we added the second Y axis to the right-hand edge of the plot. As we show below, the axis can be placed anywhere within the frame, even outside the plot.

[ChIPS output]
Postscript version
set_preference("curve.symbol.style","none");
set_preference("axis.offset.perpendicular","30");

add_window(6.0,3.0,"inches");

add_curve("aspect.fits[cols time,ra]",{"plot.style","open"});
reposition_plot(0.25,0.25,0.95,0.9);

set_xaxis({"majortick.interval",1000.0,"tickformat","%.0f"});
variable ay = ChipsAxis;
ay.ticklabel.angle = 45.0;
ay.majortick.interval = 5.0e-3;
ay.tickformat = "%.3f";
ay.minortick.count = 4;
set_yaxis(ay);

add_label(6.80096e7,259.258,"RA");

% Place the second Y axis to the left of the original axis
add_axis(Y_AXIS,-0.15,1.0,10.0);
add_curve("aspect.fits[cols time,dec]",{"line.color","red"});
limits(Y_AXIS,AUTO,AUTO);

add_label(6.80096e7,67.1965,"Dec",{"color","red"});

set_cascading_property("ay2",chips_axis,"color","red");
ay = ChipsAxis;
ay.ticklabel.angle = 45.0;
ay.majortick.interval = 2.0e-3;
ay.tickformat = "%.3f";
ay.minortick.count = 3;
ay.offset.perpendicular = 60;
set_yaxis(ay);

set_axis("all",{"majortick.mode","interval"});

set_plot_xlabel("Time (s)");

Other than positioning the axis outside the plot, the only major differences to the previous example are:

  1. Labels in the plot are used to indicate the data type, rather than axis labels. Note that these labels are positioned in data coordinates, which means that the Y values are very different for the two calls to add_label, namely 259.258 and 67.1965, even though they end up being close to each other.

    An alternative would have been to place the labels in plot-normalized coordinates using something like:

    add_label(0.1, 0.85, "RA", {"coordsys", PLOT_NORM});
    add_label(0.1, 0.75, "Dec", {"coordsys", PLOT_NORM, "color", "red"});
    
  2. The use of the set_cascading_property command to set all the *.color attributes of the second Y axis - such as label.color and majortick.color - to the value "red".

Changes in CIAO 4.1

  • In the CIAO 4.0 version of this example, the second Y axis was positioned using frame-normalized coordinates, at a position of x=0.12 (i.e. twelve percent along the width of the frame). In CIAO 4.1 axes can no longer be positioned using the frame-normalized coordinate system so the example now places the second Y axis at a position of x=-0.15 using plot-normalized coordinates, which is a distance outside the plot equal to fifteen percent of the width of the plot (i.e. width of the X axis).

Last modified: 9 July 2009


The Chandra X-Ray Center (CXC) is operated for NASA by the Smithsonian Astrophysical Observatory.
60 Garden Street, Cambridge, MA 02138 USA.    Email: cxcweb@head.cfa.harvard.edu
Smithsonian Institution, Copyright © 1998-2004. All rights reserved.