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 2008
Hardcopy (PDF): A4 | Letter

ChIPS - using symbols to draw sets of (x,y) points

ChIPS Threads (CIAO 4.0)

[Python Syntax]



Overview

Last Update: 9 Jul 2008 - New for CIAO 4.0

Synopsis:

This thread is intended to give a simple demonstration of the support for symbols and error bars in ChIPS. It also includes examples of how ASCII files can be used in ChIPS (and in other CIAO tools), as well as how data can be plotted directly from a file or read into Python, manipulated, and then sent to ChIPS. Additional capabilities, such as annotating the plot with lines and labels, changing the order items are drawn, and use of multiple plots are included.

Proceed to the HTML or hardcopy (PDF: A4 | letter) version of the thread.




Contents



Introduction

The Starting ChIPS thread describes how to start ChIPS.

The data used in this thread is available in the chips_data.tar.gz file.

unix% ls -1 chips/curve_symbol/
axes.state
bax.lis
plot-z-fx.state
z-tx-error2.state
z-tx-region-back.state

The plots used in this thread are based on the data in the text file bax.lis which contains the contents of the BAX Galaxy Cluster Database. The data was obtained from the VizieR catalogue service and converted into a form that could be recognized by the ASCII kernel of the CIAO Data Model.

The file consists of columns separated by the | character and looks like:

unix% head bax.lis
#name|ra|dec|z|fx|lx|tx|telo|tehi
MS1008.1-1224|152.6423|-12.6632|0.301|3.02e+00|1.10e+01|7.20|0.80|1.00
ABELL1656|194.9531|+27.9807|0.023|3.44e+02|7.77e+00|8.25|0.10|0.10
RXJ1120.1+4318|170.0312|+43.3014|0.600|4.20e-01|6.07e+00|5.45|0.30|0.30
RXJ1053.7+5735|163.4308|+57.5892|1.263|2.64e-02|1.92e+00|3.90|0.20|0.20
RXJ0123.6+3315|020.9167|+33.2556|0.016|1.71e+01|1.98e-01||| 
ABELL3112|049.4683|-44.2429|0.075|3.10e+01|7.37e+00|4.72|0.15|0.22
FORNAXCLUSTER|054.6289|-35.4545|0.005|9.02e+01|8.16e-02|1.56|0.04|0.03
IIIZW054|055.3242|+15.3961|0.029|2.00e+01|7.19e-01||| 
ABELL3158|055.6652|-53.6306|0.060|3.79e+01|5.65e+00|5.41|0.14|0.16
unix% dmlist "bax.lis[opt sep=|]" cols
 
--------------------------------------------------------------------------------
Columns for Table Block bax.lis
--------------------------------------------------------------------------------
 
ColNo  Name                 Unit        Type             Range
   1   name                              String[1024]                        
   2   ra                                Real8          -Inf:+Inf            
   3   dec                               Real8          -Inf:+Inf            
   4   z                                 Real8          -Inf:+Inf            
   5   fx                                Real8          -Inf:+Inf            
   6   lx                                Real8          -Inf:+Inf            
   7   tx                                Real8          -Inf:+Inf            
   8   telo                              Real8          -Inf:+Inf            
   9   tehi                              Real8          -Inf:+Inf            

The [opt sep=|] text is needed to tell the Data Model that the column separator is | (the default value is white space). The column names are taken from the single comment line at the head of the file (which is also separated by | characters). The following example shows how the statistics of the redshift (i.e. z) column can be calculated using the dmstat tool (numeric columns with no data are given 0 values, which is why the minimum redshift reported by dmstat is 0):

unix% dmstat "bax.lis[cols z][opt sep=|]" sig-
z
    min:        0             @:        154 
    max:        1.301         @:        1133 
   mean:        0.15674022183 
    sum:        268.496 
   good:        1713 
   null:        0 

The remaining files (all ending in ".state") are ChIPS state files, representing the finished versions of the plots created below: plot-z-fx.state (Figure 6); z-tx-region-back.state (Figure 10); z-tx-error2.state (Figure 12); and axes.state (Figure 17). These files allow you to view, and edit, the visualizations without having to enter in all the preceeding commands.



Symbol support for curves

In this section we are going to plot up the flux versus redshift values from the file bax.lis, varying the symbol used to mark the points to highlight the symbol support for curves in ChIPS. Since the file is not ordered by redshift we will turn off the lines connecting the points by setting the line.style attribute to none. The call to clear is not needed if ChIPS has just been started.

chips> clear()
chips> make_figure("bax.lis[cols z,fx][opt sep=|]")
chips> set_curve(["line.style","none"])
chips> log_scale()
[Thumbnail image: A curve drawn with the default symbol style (cross) to mark the points]

[Version: full-size, PNG, postscript]

[Print media version: A curve drawn with the default symbol style (cross) to mark the points]

Figure 1: Flux versus redshift using the default symbol style

The make_figure command has created a plot of the fx versus z columns from the file bax.lis. The default symbol style (cross) is used to indicate the points; the line drawn between the points has been turned off by setting the line.style attribute to none.

ChIPS supports a range of symbol styles, such as a cross or a square, and these symbols can be drawn filled or open. The default values are to use a filled cross, as shown in Figure 1, and the following (Figure 2) show how the plot looks when an open square is used instead.

chips> set_curve(["symbol.style","square","symbol.fill",0])
[Thumbnail image: A curve drawn with an open square to mark the points]

[Version: full-size, PNG, postscript]

[Print media version: A curve drawn with an open square to mark the points]

Figure 2: Flux versus redshift: open square

The symbol style has been changed to a square, and the symbol.fill attribute turned off.

The symbol size can also be changed. The value used in Figure 2 is 5 (as returned by get_curve), with the valid range being 1 to 100, inclusive.

chips> print get_curve().symbol.size
5
chips> set_curve(["symbol.size",1])
chips> set_curve(["symbol.size",2])
[Thumbnail image: The symbol size has been reduced from a value of 5 to 2]

[Version: full-size, PNG, postscript]

[Print media version: The symbol size has been reduced from a value of 5 to 2]

Figure 3: Flux versus redshift: smaller squares

The symbol size has been changed from its default value of 5, which was used in Figure 2, to 2.

The point symbol style is a special case in that its appearance is not changed by the symbol.fill and symbol.size attributes of the curve.

chips> set_curve(["symbol.style","point"])
[Thumbnail image: Symbols are now drawn as a single point]

[Version: full-size, PNG, postscript]

[Print media version: Symbols are now drawn as a single point]

Figure 4: Flux versus redshift: the point style

The symbol style has been changed to point.

We add a second curve which consists of just the hot (Tx > 6 keV) clusters. A Data Model filter is used to select the points to plot, and the ChipsCurve object is used to set the attributes of the curve to make the new curve appear as red points.

chips> ci = ChipsCurve()
chips> ci.symbol.style = "point"
chips> ci.symbol.color = "red"
chips> ci.line.style = "none"
chips> add_curve("bax.lis[tx>6][cols z,fx][opt sep=|]",ci)
[Thumbnail image: Points from hot clusters are marked with a red point]

[Version: full-size, PNG, postscript]

[Print media version: Points from hot clusters are marked with a red point]

Figure 5: Flux versus redshift: highlighting a subset of points

A second curve has been added to the plot. This curve represents the hot (Tx > 6 keV) clusters and is drawn using red points.

In order to make these points more visible we change the symbol style to a small square rather than a point:

chips> ci.symbol.style = "square"
chips> ci.symbol.size = 2
chips> set_curve(ci)

The plot is completed by adding annotations to help identify the samples. Note that the valign attribute of the labels is set to 0.5 so that they are vertically centered on the associated point. A region has been used to draw a rectangle around the text and points (undo is useful here when trying to adjust the spacing of the box around the contents).

chips> add_point(0.2, 600, ["style","point"])
chips> add_point(0.2, 300, ["style","square","size",2,"color","red"])
chips> add_label(0.23, 600, r"kT_x \leq 6 keV", ["valign", 0.5])
chips> add_label(0.23, 300, "kT_x > 6 keV", ["valign", 0.5, "color", "red"])
chips> xr = [0.16, 0.9, 0.9, 0.16]
chips> yr = [170, 170, 900, 900]
chips> add_region(xr, yr)
chips> print_window("plot-z-fx",["format","eps"])
chips> print_window("plot-z-fx",["format","png"])
chips> save_state("plot-z-fx.state")

Figure 6: Flux versus redshift: the final plot

The second curve shown in Figure 5 has been removed and replaced by one which uses small red squares, since this is more visible. Two labels have been added to indicate what the curves are, and a region has been used to draw a box around these labels.

The ChIPS state file plot-z-fx.state is included in chips_data.tar.gz and can be loaded by saying:

chips> load_state("plot-z-fx.state")


Handling data from a file

In this section we shall read in the data from bax.lis into Python using Crates, show how ChIPS handles values less than 0 when using a logarithmic axis scale, and use a region to highlight a portion of the plot.

First we read in the file using read_file, and extract the data for the redshift (z) and temperature (tx) columns.

chips> cr = read_file("bax.lis[opt sep=|]")
chips> print get_col_names(cr)
['name' 'ra' 'dec' 'z' 'fx' 'lx' 'tx' 'telo' 'tehi']
chips> z = get_colvals(cr, "z")
chips> tx = get_colvals(cr, "tx")

We now use add_curve to plot these points using the open symbol style. To avoid having to turn the line style to none for any new curves we set the preference value for this attribute.

chips> clear()
chips> set_preference("curve.line.style", "none")
chips> add_curve(z, tx, ["symbol.style","circle","symbol.fill",0])
[Thumbnail image: A plot of temperature versus redshift]

[Version: full-size, PNG]

[Print media version: A plot of temperature versus redshift]

Figure 7: Temperature versus redshift: all the data

The temperature versus redshift arrays have been plotted as open circles, after being read in from the data file. The values at Tx = 0 indicate those clusters which do not have a temperature measurement in the BAX database.

Even though the data contains values that are zero, we can still change the axis scaling to logarithmic. The new limits are based on the positive data values along that axis.

chips> log_scale()
[Thumbnail image: The points at Tx = 0 are ignored when the axis scaling is changed to logarithmic.]

[Version: full-size, PNG]

[Print media version: The points at Tx = 0 are ignored when the axis scaling is changed to logarithmic.]

Figure 8: Temperature versus redshift: how does log scale handle 0 values?

The Tx axis can be changed to use a logarithmic scale even though there are points with values of 0; these points are ignored when calculating the display range for the axis.

An alternate method is to filter out the unwanted points before plotting. When creating Figure 5 we used a Data Model filter to exclude cool clusters. Now we shall use the array-filtering capabilities of Python to exclude those entries which do not have a temperature measurement (i.e. those rows with tx <= 0):

chips> i = tx > 0
chips> z2 = z[i]
chips> tx2 = tx[i]

The z2 and tx2 arrays can be used to create a plot:

chips> clear()
chips> add_curve(z2, tx2, ["symbol.style","circle","symbol.fill",0])
chips> log_scale()
chips> set_plot_xlabel ("z")
chips> set_plot_ylabel ("T_x")

We add on a horizontal line at Tx = 2, drawn with a dotted line style. A region is also added to the plot in order to highlight the redshift range z=0.2 - 0.9. The use of get_plot_yrange is to ensure that the region covers the full Y axis, and the fill.visible attribute is set so that the interior of the region is filled. The default fill.color for regions is green and the opacity is 0.5, which means that the on-screen version of the plot will show the points that lie behind the region. However, due to a limitation of the CIAO 4.0 version of ChIPS, all hardcopy versions of this plot (so anything created by print_window) will draw the region as fully opaque, so the points behind the region will not be visible. This can be seen by comparing the on-screen version of the plot to the postscript version (Figure 9).

chips> add_hline(2, ["style", "dot"])
chips> yr = get_plot_yrange()
chips> xbox = [0.2,0.9,0.9,0.2]
chips> ybox = [yr[0],yr[0],yr[1],yr[1]]
chips> add_region(xbox,ybox,["fill.visible",1])
chips> print get_region()
angle = 0.0
depth = 100
edge.color = green
edge.style = 1
edge.thickness = 1.0
fill.color = green
fill.visible = True
id = None
opacity = 0.5
stem = None

chips> print_window("z-tx-region-front")
[Thumbnail image: A filled region has been used to highlight the area between z=0.2 and 0.9.]

[Version: full-size, PNG, postscript]

[Print media version: A filled region has been used to highlight the area between z=0.2 and 0.9.]

Figure 9: Temperature versus redshift: using a filled region to highlight a band

The region is drawn in front of the curve, so those symbols that fall in the region z=0.2 - 0.9 are visible, but tinted green, in the on-screen version of the plot and are hidden in the "hardcopy" versions of the plot (i.e. any format produced by the print_window command).

In order to make the symbols visible in the hardcopy versions of the plot we move the region to a lower depth than the curve. This means that the region gets drawn before the curve (and everything else, which has the same depth value as the curve), and so will not obscure the symbols.

chips> print get_region().depth
100
chips> print get_curve().depth
100
chips> set_region(["depth",50])
chips> print_window("z-tx-region-back")
chips> save_state("z-tx-region-back.state")
[Thumbnail image: The region has been moved behind the curve so that all the data can be seen in the hardcopy formats.]

[Version: full-size, PNG, postscript]

[Print media version: The region has been moved behind the curve so that all the data can be seen in the hardcopy formats.]

Figure 10: Temperature versus redshift: moving the region behind the curve

As the region has been moved to a lower depth than the curve (and all the other elements of the plot), it is drawn first, and so does not obscure the other elements in the hardcopy versions of the plot. This can be seen by comparing the postscript output of this figure to that of Figure 9.

The ChIPS state file z-tx-region-back.state is included in chips_data.tar.gz and can be loaded by saying:

chips> load_state("z-tx-region-back.state")


Error bars and limits

So far all the data we have plotted has not included error bars. As the BAX database includes errors for the temperature values (given as asymmetric values using the telo and tehi columns), we can use the data to highlight the support for error bars in ChIPS.

For the first plot we will assume symmetric error bars, so we decide to use the average value of the upper and lower error bars for illustrative purposes only. Since we want to exclude the values without temperatures or temperature errors, we filter out these values (and create the index array j):

chips> txlo = get_colvals(cr, "telo")
chips> txhi = get_colvals(cr, "tehi")
chips> txlo2 = txlo[i]
chips> txhi2 = txhi[i]
chips> dtx2 = 0.5 * (txlo2 + txhi2)
chips> j = dtx2 > 0

The data can be plotted: if add_curve is given three 1D columns of data then it assumes they are x,y,dy values. The axis scale can be changed between linear and logarithmic scales, even when the data includes error bars. The resulting plot is shown in Figure 11.

chips> clear()
chips> add_curve (z2[j], tx2[j], dtx2[j])
chips> log_scale()
chips> set_curve(["symbol.style","square","symbol.fill",0,"symbol.size",2])
chips> set_plot_xlabel ("redshift")
chips> set_plot_ylabel ("Temperature (keV)")
chips> set_plot_title ("BAX clusters with temperature errors")
[Thumbnail image: Symmetric errors for the temperature values.]

[Version: full-size, PNG, postscript]

[Print media version: Symmetric errors for the temperature values.]

Figure 11: Temperature versus redshift: symmetric errors

Symmetric error bars have been drawn for the temperature measurements. These errors were calculated as the average of the upper and lower error bard for the data and so are only for illustrative purposes.

If the third argument to add_curve is not a 1D vector but a list of 1D vectors, then the values of the third argument are taken to be one of:

  • low y error, high y error
  • low y error, high y error, low x error
  • low y error, high y error, low x error, high x error

We can therefore plot the asymmetric temperature errors using the following (where we re-use the index array j to exclude points with no error data). The error-bar style is changed from the default value of bar - as used in Figure 11 - to cap, and the colors of the error bars and symbols are also changed. The plot title is changed to be aligned to the left of the plot - by setting both title.halign and title.xpos to 0 and to use the times font.

chips> clear()
chips> add_curve (z2[j], tx2[j], [txlo2[j], txhi2[j]])
chips> set_curve(["symbol.style","diamond","symbol.fill",0,"symbol.size",4])
chips> set_curve(["err.style", "cap", "err.color", "red"])
chips> set_curve(["symbol.color","skyblue"])
chips> set_plot_title ("Asymmetric error bars")
chips> set_plot(["title.halign", 0, "title.xpos", 0, "title.font", "times"])
chips> log_scale()
chips> save_state("z-tx-error2.state")
[Thumbnail image: Asymmetric errors for the temperature values.]

[Version: full-size, PNG, postscript]

[Print media version: Asymmetric errors for the temperature values.]

Figure 12: Temperature versus redshift: asymmetric errors

Asymmetric error bars have been drawn for the temperature measurements. The properties of the curve (error bar style, color, and symbol color) have been changed from their default values. Similarly, the plot title has been adjusted so that it is left-aligned with the plot and uses a different font than normal (times rather than helvetica).

The ChIPS state file z-tx-error2.state is included in chips_data.tar.gz and can be loaded by saying:

chips> load_state("z-tx-error2.state")

The following show the settings of some of the elements of the figure - the symbol and error settings of the curve and the title settings of the plot.

chips> print get_curve().symbol
angle = 0.0
color = skyblue
fill = False
size = 4
style = 2

chips> print get_curve().err
color = red
down = True
left = False
right = False
style = capped
thickness = 1.0
up = True

chips> print get_plot().title
angle = 0.0
color = default
depth = 100
font = times
fontstyle = normal
halign = 0
size = 16
valign = 0.5
xpos = 0
ypos = 15.0

In order to show error bars on the X axis we are going to use some invented data: y = sqrt(x) where the fractional error on y is 10% and the absolute error on x is 0.1. We set up the a, da, b, and db arrays with these values:

chips> a = numpy.arange(1,10,0.5)
chips> da = a * 0 + 0.1
chips> b = numpy.sqrt(a)
chips> db = b / 10.0

Now we can plot the data. We first create two plots, arranged vertically, using split, and then change the currency so that both plots are current. This means that the add_curve call creates curves in both plots. The second plot is selected (made "current") so that the set_curve call only changes the error-bar style of the curve in the bottom plot.

chips> clear()
chips> split(2)
chips> print info()
Window [win1]
  Frame [frm1]
    Plot [plot1]   (0.15,0.52)  .. (0.90,0.90)
      Border bottom [bx1]  top [bx2]  left [by1]  right [by2]
    Plot [plot2]   (0.15,0.15)  .. (0.90,0.52)
      Border bottom [bx1]  top [bx2]  left [by1]  right [by2]

chips> print info_current()
Window [win1]
  Frame [frm1]
    Plot [plot1]
    Coord Sys [Plot Normalized]

chips> current_plot("all")
chips> print info_current()
Window [win1]
  Frame [frm1]
    Plot [plot1]
    Plot [plot2]

chips> add_curve (a, b, [db, db, da, da], ["symbol.style","none"])
chips> print info_current()
Window [win1]
  Frame [frm1]
    Plot [plot1]
      X Axis [ax1]
      Y Axis [ay1]
      Curve [crv1]
    Plot [plot2]
      X Axis [ax1]
      Y Axis [ay1]
      Curve [crv1]

chips> current_plot("plot2")
chips> print info_current()
Window [win1]
  Frame [frm1]
    Plot [plot2]
      X Axis [ax1]
      Y Axis [ay1]
      Curve [crv1]
    Coord Sys [Data]
    Coord Sys ID [plot2_ax1ay1]

chips> set_curve(["err.style","cap"])
chips> adjust_grid_ygap (0.05)

Note that although the two curves were created by a single call, they are independent objects once they have been created, as shown by the fact you can change the err.style attribute of the curve in the second plot.

[Thumbnail image: The two plots show errors on both X and Y values; the bottom plot uses the capped style for the errors.]

[Version: full-size, PNG, postscript]

[Print media version: The two plots show errors on both X and Y values; the bottom plot uses the capped style for the errors.]

Figure 13: Error bars on both X and Y values

The two plots show the same data: y = sqrt(x) with 10% errors on y and an absolute x error of 0.1. The only difference in the two plots is that the err.style of the curve in the top plot has the default value of bar, whereas for the lower plot the curve's attribute has been changed to cap.

We finish this section with a brief discussion for the preliminary support of limits in ChIPS. Limits are indicated by supplying, along with the error values, a vector with values of 1 for an upper limit, -1 for a lower limit, and 0 to indicate that the value from the error array should be used instead. We create such an array and set the third and last-but-one elements to indicate upper and lower limits respectively (for the a,b arrays we used to create Figure 13).

chips> lim = numpy.zeros(len(a),dtype="int8")
chips> lim[2] = 1
chips> lim[-2] = -1

When plotted (see Figure 14) the third and last-but-one points are drawn as limits rather than errors. Although not shown here, the limits array can be replaced by a list of vectors - the same number as used for the error values - if limits along different axes are needed.

chips> clear()
chips> add_curve (a, b, [db, db, da, da], lim, ["symbol.style","none"])
[Thumbnail image: The third point is drawn with an upper-limit symbol and the last-but-one point is drawn with a lower-limit symbol.]

[Version: full-size, PNG, postscript]

[Print media version: The third point is drawn with an upper-limit symbol and the last-but-one point is drawn with a lower-limit symbol.]

Figure 14: Y limits

The same data as shown in Figure 13 has been plotted, but this time limits are indicated for the third and last-but-one points.

Note: the limits start - rather than end - at the data point (here the a,b values).

Currently there are only two attributes that control the appearance and behavior of limits:

chips> print get_curve().limit
length = 0.0500000007451
override = True

Their affect can be seen in Figure 15:

chips> split(2,1,0.05)
chips> add_curve (a, b, [db, db, da, da], l, ["symbol.style","none"])
chips> set_curve(["limit.length",0.1,"limit.override",0])
[Thumbnail image: The limit.length and limit.override attributes control the appearance of the limits]

[Version: full-size, PNG, postscript]

[Print media version: The limit.length and limit.override attributes control the appearance of the limits]

Figure 15: Changing the appearance of limits

The limit.length attribute controls the length of the line drawn to indicate the limit. The limit.override attribute determines whether the opposite error bar should be drawn (false or 0) or not (true or 1).



Customizing the appearance of the axes

In this section we show some of the customizations that can be applied to axes, in particular: adjusting the position of the labels, changing the format used to draw the numeric labels, adding an extra axis to a plot, and changing the labeling of the axis.

The plot will be of the X-ray luminosity versus redshift of the clusters in the BAX database. The lx column is in units of 1044 erg/s, so we multiply by this value when creating the curve. The format for the numeric tick marks is changed for the Y axis to use the %Z format, which causes the value 1.0e44 to be written as 1 x 1044.

chips> lx = get_colvals(cr, "lx")
chips> clear()
chips> add_curve (z, lx*1e44, ["symbol.style", "point"])
chips> log_scale;
chips> set_plot_xlabel ("Redshift")
chips> set_plot_ylabel ("L_x (erg s^{-1})")
chips> set_yaxis(["tickformat", "%Z"])

With the new label format, the label for the Y axis overlaps the ticklabels. We can, and will, increase the separation between the axis label and the axis, but first we increase the left plot margin - from 0.15 to 0.2 - to give more space.

chips> print get_plot().leftmargin
0.15000000596
chips> set_plot(["leftmargin", 0.2])

There are many attributes that change the appearance of axes; here we concentrate on those that control the appearance of the labels that appear at the positions of the major tick marks on the Y axis:

chips> print get_yaxis().ticklabel
angle = 0.0
color = default
font = helvetica
fontstyle = normal
halign = -99.0
offset = 6
size = 12
style = outside
valign = -99.0
visible = True

We decide to increase the size of these labels, from 12 to 16, and we use the set_axis call to change both the X and Y axes at the same time. There is a bug in CIAO 4.0 which means that a change to the ticklabel.size attribute is not immediately recognized when the tickformat value is %z or %Z. We therefore follow the size change with a call to set the ticklabel.color value to default; although this does not actually change anything, it does make the Y axis update the display of the ticklabels to use the new size value of 16. To stop the axis label from overlapping the ticklabels we increase the offset.perpendicular value from 40 to 65 (the units of this attribute is pixels).

chips> set_axis(["ticklabel.size", 16])
chips> set_axis(["ticklabel.color", "default"])
chips> print get_yaxis().offset
parallel = 0.0
perpendicular = 40.0

chips> set_yaxis(["offset.perpendicular", 65])

We now want to add an X axis to the top of the plot that indicates the luminosity distance to the clusters. We start by adding an X-axis to the top of the plot - a value of y = 1 in the PLOT_NORM coordinate system indicates the top of the plot area - and ensure that it has thee same range as the existing X axis (by use of get_plot_xrange). The pad attribute is set to 0 to make sure that these limits are not automatically expanded when the axis is created (since the default value for the attribute is 0.05), and the id attribute set to make it easier in later calls to identify which axis is which. As the new X axis is now the current X axis, the log_scale call changes the scaling of just this axis. The current state of the plot is shown in Figure 16.

chips> id = ChipsId()
chips> id.coord_sys = PLOT_NORM
chips> xr = get_plot_xrange()
chips> add_axis (id, X_AXIS, 1, xr[0], xr[1], [ "pad", 0, "id", "dl" ])
chips> log_scale (X_AXIS)
[Thumbnail image: The top border of the plot has been replaced by another axis.]

[Version: full-size, PNG, postscript, PDF]

[Print media version: The top border of the plot has been replaced by another axis.]

Figure 16: Adding a second X axis to the plot

An extra X axis has been added to the top of the plot. At the moment it has the same range, scaling, and labels as the bottom X axis (although the size of the ticklabels is smaller).

We now want to label the luminosity distances along this axis. We have calculated that the 100, 1000, and 10000 Mpc luminosity distances correspond to z = 0.0166, 0.16079, amd 1.37052 for the cosmology used for the BAX database (an Einstein-de Sitter universe with H0 = 50 km/s/Mpc), so we can use the set_arbitrary_tick_positions call to add major tick marks at these positions. The new axis is explicitly identified in this call - i.e. the first argument is set to "dl" - otherwise the Y axis would also have been changed by this call. Since the minor tick marks have no meaning for this axis (as the scaling is neither linear or logarithmic), we turn them off by setting the minortick.visible attribute to 0.

chips> xl = ["100", "1000", "10000"]
chips> zr = [0.0166, 0.16079, 1.37502]
chips> set_arbitrary_tick_positions ("dl", zr, xl)
chips> set_xaxis (["minortick.visible",0])
chips> print info_current()
Window [win1]
  Frame [frm1]
    Plot [plot1]
      Y Axis [ay1]
      Curve [crv1]
      X Axis [dl]
    Coord Sys [Data]
    Coord Sys ID [plot1_dlay1]

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

As the new X axis is still current we can easily add a label to it and decrease the separation between the label and the new axis. To make the most use of the space we decrease the right margin of the plot from 0.1 to 0.05.

chips> set_plot_xlabel ("Luminosity Distance (Mpc)")
chips> print get_xaxis().offset
parallel = 0.0
perpendicular = 40.0

chips> set_xaxis(["offset.perpendicular", 25])
chips> print get_plot().rightmargin
0.10000000149
chips> set_plot(["rightmargin",0.05])

Finally we print out the plot after changing the symbol to the smallest sized circle provided by ChIPS. The postscript and PDF versions are scaled up to fit a US letter page whilst keeping the aspect ratio of the plot fixed.

chips> set_curve(["symbol.style","circle","symbol.size",1])
chips> print_window("axes",["fittopage",1])
chips> print_window("axes",["fittopage",1,"format","pdf"])
chips> print_window("axes",["format","png"])
chips> save_state("axes.state")
[Thumbnail image: The plot shows some of the customizations that can be made to axes and plots.]

[Version: full-size, PNG, postscript, PDF]

[Print media version: The plot shows some of the customizations that can be made to axes and plots.]

Figure 17: Customized axes

The final plot shows customizations applied to both axes. The Y axis has been changed to use scientific notation (i.e. 1 x 1042) and the label has been moved so that it no longer overlaps the ticklabels. Both the Y axis and the bottom (original) X axis have had the size of the ticklabels increased.

The second X axis, added at the top of the plot, has been adjusted so that it shows representative luminosity distance values. Since the scaling between redshift and luminosity distance is not linear or logarithmic, the minor tick marks have been hidden for this axis.

The plot margins have been adjusted so that the plot makes full use of the space it occupies, and to allow the labels on the Y axis to be moved so they do not overlap.

The ChIPS state file axes.state is included in chips_data.tar.gz and can be loaded by saying:

chips> load_state("axes.state")



Summary



History

09 Jul 2008 New for CIAO 4.0

Return to Threads Page: Top | All | Intro
Hardcopy (PDF): A4 | Letter
Last modified: 9 July 2008


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.