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 - displaying histogram data

ChIPS Threads (CIAO 4.0)

[Python Syntax]



Overview

Last Update: 9 Jul 2008 - New for CIAO 4.0

Synopsis:

This thread demonstrates some of the capabilities for displaying histogram data in ChIPS. This includes support for binned data that is given as either (xmid,y) or (xlo,xhi,y), errors on the Y value (symmetric or asymmetric), marking the bins with symbols, and coloring the histogram interior.

We also include other features in ChIPS, such as the support for multiple plots - including plots within plots - and for multiple axes within plots to allow different data to be shown on the same plot.

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/histogram/
attr-fill-back.state
attr-fill-opaque.state
axis2-xzoom.state
compare1.state
err-mid.state
lc.fits
pip.state
sym-circle-fill.state

The plots used in this thread are based on the light curve data used in the CIAO filtering lightcurves thread, renamed to lc.fits. The contents of the file are:

unix% dmlist lc.fits cols
 
--------------------------------------------------------------------------------
Columns for Table Block LIGHTCURVE
--------------------------------------------------------------------------------
 
ColNo  Name                 Unit        Type             Range
   1   TIME_BIN             channel      Int4           1:153                S/C TT corresponding to mid-exposure
   2   TIME_MIN             s            Real8          77377470.9496479928: 77408016.4632720053 Minimum Value in Bin
   3   TIME                 s            Real8          77377470.9496479928: 77408016.4632720053 S/C TT corresponding to mid-exposure
   4   TIME_MAX             s            Real8          77377470.9496479928: 77408016.4632720053 Maximum Value in Bin
   5   COUNTS               count        Int4           -                    Counts
   6   STAT_ERR             count        Real8          -Inf:+Inf            Statistical error
   7   COUNT_RATE           count/s      Real8          -Inf:+Inf            Rate
   8   COUNT_RATE_ERR       count/s      Real8          -Inf:+Inf            Rate Error
   9   EXPOSURE             s            Real8          -Inf:+Inf            Time per interval

The remaining files (all ending in ".state") are ChIPS state files, representing the finished versions of the plots created below: compare1.state (Figure 2); attr-fill-opaque.state (Figure 6); attr-fill-back.state (Figure 7); sym-circle-fill.state (Figure 15); err-mid.state (Figure 19); pip.state (Figure 22); and axis2-xzoom.state (Figure 28). These files allow you to view, and edit, the visualizations without having to enter in all the preceeding commands.



Drawing a histogram of xmid,y data values

The histogram support in ChIPS allows you to draw a histogram of previously-binned data - given as either xmid,y or xlo,xhi,y - but does not perform the binning for you. The creation of the histogram can be performed by CIAO tools like dmextract and dmcopy, or by routines in the Python language.

In this section we show how you can use make_figure and add_histogram routines to draw histograms of the TIME_BIN and COUNTS columns from lc.fits.

chips> make_figure ("lc.fits[cols time_bin,counts]","histogram")
chips> print 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]
      Histogram [hist1]

chips> print_window ("basic")
chips> print_window ("basic",["format","png"])
[Thumbnail image: The X axis shows the TIME_BIN column and the Y axis the COUNTS column.]

[Version: full-size, PNG, postscript]

[Print media version: The X axis shows the TIME_BIN column and the Y axis the COUNTS column.]

Figure 1: A basic histogram created by make_figure

The make_figure command has drawn a histogram of the TIME_BIN,COUNTS columns from the file lc.fits.

Unlike the case of creating curves (for example, when creating the latitude versus time figure), the figuretype argument to make_figure must be supplied when creating histograms.

We now show how the same data is displayed as a curve, to highlight the differences in appearance and behavior of the two objects in ChIPS. To make it easier to compare the two, we add a second plot, arranged vertically below the first one, using the split command, and add the curve to it. To remove the overlapping labels we remove the title of the second - i.e. bottom plot - and the X-axis label of the first plot by setting them both to "". The result is shown in Figure 2.

chips> split (2)
chips> make_figure ("lc.fits[cols time_bin,counts]",["symbol.style","none"])
chips> set_plot_title ("")
chips> set_plot_xlabel ("plot1", "")
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]
      X Axis [ax1]
      Y Axis [ay1]
      Histogram [hist1]
    Plot [plot2]   (0.15,0.15)  .. (0.90,0.52)
      Border bottom [bx1]  top [bx2]  left [by1]  right [by2]
      X Axis [ax1]
      Y Axis [ay1]
      Curve [crv1]

chips> save_state("compare1.state")
[Thumbnail image: The histogram is drawn with a horizontal line between the low and high edges of each bin, whereas the curve draws a straight line between the mid-points of the bin.]

[Version: full-size, PNG, postscript]

[Print media version: The histogram is drawn with a horizontal line between the low and high edges of each bin, whereas the curve draws a straight line between the mid-points of the bin.]

Figure 2: Comparing histograms and curves

Data in x,y format can be drawn as a histogram (top plot) or a curve (bottom plot).

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

chips> load_state("compare1.state")

A careful inspection of the X-axes in Figure 2 shows that they do not quite line up; the histogram plot covers a slightly-larger range, as also shown by the return value of the get_plot_xrange calls.

chips> print get_plot_xrange("plot1")
[-7.1500000000000004, 161.15000000000001]
chips> print get_plot_xrange("plot2")
[-6.6000000000000005, 160.59999999999999]

The reason for this difference is because the histogram is drawn from the start to end of each bin, whereas the curve uses the mid-point of the bin. This is graphically shown in Figure 3, which was created using the following commands:

chips> clear()
chips> add_histogram ("lc.fits[cols time_bin,counts]")
chips> add_curve ("lc.fits[cols time_bin,counts]")
chips> set_curve (["line.color","red","line.style","dot"])
chips> set_curve (["symbol.color","green","symbol.style","circle"])
chips> limits (X_AXIS, 140,155)
chips> limits (Y_AXIS, -20,600)
chips> print 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]
      Histogram [hist1]
      Curve [crv1]

[Thumbnail image: The curve does not extend as far, in the X direction, as the histogram.]

[Version: full-size, PNG, postscript]

[Print media version: The curve does not extend as far, in the X direction, as the histogram.]

Figure 3: How are curves and histograms displayed?

The red dotted line and green circles indicate the curve, whereas the solid line (white on screen, black in the hardcopy output) is the histogram. The curve ends at the last point (x=153) whereas the histogram extends past this to the edge of the bin (x=153.5).



Controlling the appearance of histograms

As with curves, the appearance of histograms can be controlled by a set of attributes. The get_histogram and set_histogram routines are used to report and change these attributes. In the example below we change the histogram to be drawn in blue, and force each bin edge to be drawn down to y=0 (the default setting is to only do this for the start and end bins). The resulting figure is shown in Figure 4.

chips> clear()                   
chips> add_histogram ("lc.fits[cols time_bin,counts]")
chips> print get_histogram()
depth = 100
dropline = False
err.color = default
err.down = False
err.style = line
err.thickness = 1.0
err.up = False
fill.color = default
fill.opacity = 1.0
fill.visible = False
id = None
line.color = default
line.style = 1
line.thickness = 1.0
stem = None
symbol.angle = 0.0
symbol.color = default
symbol.fill = False
symbol.size = 5
symbol.style = 0

chips> set_histogram (["line.color","blue","dropline","true"])
[Thumbnail image: The dropline and line.color attributes change the plot appearance.]

[Version: full-size, PNG, postscript]

[Print media version: The dropline and line.color attributes change the plot appearance.]

Figure 4: Changing the line used to draw the histogram

The dropline attribute, when set to true or 1, causes all bin edges of the histogram to be drawn down to y=0. When set to false or 0, only the start of the first bin and end of the last bin are forced to be drawn like this.

The default attribute settings for histograms can be found by saying:

chips> print get_preference ("histogram")
histogram.stem         : hist
histogram.depth        : default
histogram.line.color   : default
histogram.line.thickness: 1
histogram.line.style   : solid 
histogram.symbol.color : default
histogram.symbol.style : none
histogram.symbol.size  : 5
histogram.symbol.angle : 0
histogram.symbol.fill  : false
histogram.err.color    : default
histogram.err.thickness: 1
histogram.err.style    : line 
histogram.err.up       : on
histogram.err.down     : on
histogram.dropline     : off
histogram.fill.color   : default
histogram.fill.visible : false
histogram.fill.opacity : 1

We now remove the last change, using undo, and then set the fill.visible attribute to 1 so that the histogram is drawn with a filled interior, which we also set to be red. The result is shown in Figure 5.

chips> undo()
chips> set_histogram (["fill.color","red","fill.visible",1])
chips> log_scale (Y_AXIS)
[Thumbnail image: The interior of the histogram has been filled with a solid red color.]

[Version: full-size, PNG, postscript]

[Print media version: The interior of the histogram has been filled with a solid red color.]

Figure 5: A filled histogram

The fill.* attributes of a histogram determine if, and how, the histogram is to be filled. In this case, because fill.opacity is set to 1, the interior is set to be filled with red, and is opaque. This is why the tick labels along the X axis are hidden by the histogram.

The y limits of the plot are based on the range of the positive y values, in this case 29 to 2947 (see dmstat output below), since we have changed the plot to use a logarithmic scale for the Y axis.

chips> !dmstat "lc.fits[counts > 0][cols counts]" cen- | egrep 'min|max'
    min:        29            @:        1 
    max:        2947          @:        111 

For CIAO 4.0, the hardcopy output of filled regions and histograms is not ideal in that you can often see faint structures (lines). This happens for all the hardcopy formats - e.g. look at the PNG and postscript outputs for this figure.

There are two ways to stop the filled region from overlapping the X axis in Figure 5. The first option - shown in Figure 6 - is to reduce the fill.opacity setting from 1:

chips> set_histogram (["fill.opacity",0.4])
chips> save_state("attr-fill-opaque.state")
[Thumbnail image: The X-axis tick labels are now visible, but colored pink, since the opacity of the red fill has been reduced.]

[Version: full-size, PNG, postscript]

[Print media version: The X-axis tick labels are now visible, but colored pink, since the opacity of the red fill has been reduced.]

Figure 6: Reducing the opacity of a filled histogram

By reducing the opacity of the histogram fill - which is controlled by the fill.opacity attribute - the tick labels on the X axis can be seen, although they are tinted red.

In CIAO 4.0, the hardcopy output of filled regions ignores the fil.opacity setting, and treats it as 1. This happens for all the hardcopy formats - e.g. look at the PNG and postscript outputs for this figure.

The ChIPS state file attr-fill-opaque.state is included in chips_data.tar.gz and can be loaded by saying:

chips> load_state("attr-fill-opaque.state")

The alternative, shown in Figure 7, is to move the histogram so that it is drawn before the axes. One way to do this is to change the depth attribute of the histogram so that it is less than all other elements of the plot. An example of how to do this is shown when creating Figure 10 of the "symbol support in curves" thread. The other way is to shuffle the histogram backwards so that it is drawn behind all the other elements at its depth (the call to undo is just to remove the opacity change used to create Figure 6):

chips> undo()
chips> shuffle_histogram (chips_back)
chips> print info_depth()
Window [win1]
  Frame [frm1]
    Depth 100
      histogram [hist1 (plot1)]
      label [title (plot1)]
      axis [bx1 (plot1)]
      axis [bx2 (plot1)]
      axis [by1 (plot1)]
      axis [by2 (plot1)]
      axis [ax1 (plot1)]
      axis [ay1 (plot1)]

chips> save_state("attr-fill-back.state")
[Thumbnail image: The X-axis tick labels are now visible, since they are drawn over the top of the filled histogram.]

[Version: full-size, PNG, postscript]

[Print media version: The X-axis tick labels are now visible, since they are drawn over the top of the filled histogram.]

Figure 7: Moving the histogram behind other objects

The histogram is drawn first among all the objects with the same depth and so no-longer obscures the tick labels of the X axis (compare to Figure 5).

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

chips> load_state("attr-fill-back.state")


Adjusting the axis of a plot

So far we have used the TIME_BIN column of the light curve, which produces a readable axis but is not particularly useful. However, as shown in Figure 8, using the TIME values for Chandra data can easily produce confusing plots, since the X-axis values are large. In this section we look at how we can improve the appearance of an axis in such a situation. First we need to create the initial histogram:

chips> clear()
chips> add_histogram ("lc.fits[cols time,count_rate]")
chips> set_plot_xlabel ("Time (s)")
chips> set_plot_ylabel ("Count Rate (count s^{-1})")
[Thumbnail image: The X-axis tick labels overlap each other as they have values like "7.7405e+07".]

[Version: full-size, PNG, postscript]

[Print media version: The X-axis tick labels overlap each other as they have values like "7.7405e+07".]

Figure 8: Overlapping X-axis tick labels

Since the TIME values are large (close to 7.74 x 107 s), the default settings for the X axis cause the tick labels to overlap.

The position and spacing of the major tick marks, and hence the tick labels, are controlled by the majortick.* attributes of an axis. The default value for the majortick.mode attribute is limits, as shown below, which means that the axis limits are based on the data values or set by the user, and the tick marks are automatically calculated to cover this range. Note that the format for the ticklabels is controlled by the tickformat attribute of the axis (here it is set to %g).

chips> print get_xaxis().majortick
color = default
count = 6
interval = 10.0
length = 4
mode = limits
style = inside
thickness = 1.0
visible = True

chips> print get_xaxis().tickformat
%g

If we change the majortick.mode to interval then we can control the spacing between the major tick marks by changing the majortick.interval attribute. For the data plotted here, the axis range is close to 34 ks, so we chose a spacing of 10 ks to get three major tick marks on the X axis, as shown in Figure 9.

chips> xr = get_plot_xrange()
chips> print xr
[77375940.949647993, 77409600.949647993]
chips> print (xr[1] - xr[0])
33660
chips> set_xaxis (["majortick.mode","interval","majortick.interval",1e4])
[Thumbnail image: The spacing between the major tick marks has been increased, removing the overlap of labels.]

[Version: full-size, PNG, postscript]

[Print media version: The spacing between the major tick marks has been increased, removing the overlap of labels.]

Figure 9: Setting the spacing between major tick marks

By changing the majortick.mode mode of the X axis from limits to interval, and setting the interval to a large fraction of the axis range, the tick labels no longer overlap.

We can change the format used to create the labels; here we remove the scientific notation and avoid displaying any decimal places by setting the format to "%.0f". There are a wide range of ticklabel formats supported by ChIPS.

chips> set_xaxis (["tickformat","%.0f"])

If the majortick.mode is set to count then the majortick.count attribute determines the number of major tick marks. The axis limits may be increased by this algorithm, as they are here (Figure 10). The number of minor tick marks has been reduced to 1 using the same mode.

chips> set_xaxis (["majortick.mode","count","majortick.count",5])
chips> set_xaxis (["minortick.mode","count","minortick.count",1])
chips> print get_plot_xrange()
[77370000.0, 77410000.0]
[Thumbnail image: There are 5 major tick marks, and the X-axis has been increased so that the tick marks fall at sensible values.]

[Version: full-size, PNG, postscript]

[Print media version: There are 5 major tick marks, and the X-axis has been increased so that the tick marks fall at sensible values.]

Figure 10: Using the count major tick mode

By changing to the count mode for the major tick mode, the X-axis limits have been automatically increased.

With the mode set to count, the X-axis may not change when the limits are changed, as shown below (after the limits call the display remains showing Figure 10).

chips> limits (X_AXIS, 7.7376e7, 7.741e7)
chips> print get_plot_xrange()
[77370000.0, 77410000.0]

Changing back to the limits mode means that the X-axis will match the settings you give, and so the plot changes to the values given above (see Figure 11).

chips> set_xaxis (["majortick.mode","limits"])
chips> print get_plot_xrange()
[77376000.0, 77410000.0]
[Thumbnail image: The X axis range is now back to that set by the user.]

[Version: full-size, PNG, postscript]

[Print media version: The X axis range is now back to that set by the user.]

Figure 11: Switching back to the limits mode

When using the limits mode - which is the default value for the majortick.mode attribute - the axis will match the range given in the limits call.



Histograms of data with low and high values for the bin edges

In this section we will show you how to display data which has low and high bin edges, rather than use the middle of the bin as we did earlier. For this we need to send data arrays to the add_histogram call, rather than a file name. So first we read in the data from the file lc.fits using the Crates module:

chips> cr = read_file ("lc.fits")
chips> print get_col_names (cr)
['TIME_BIN' 'TIME_MIN' 'TIME' 'TIME_MAX' 'COUNTS' 'STAT_ERR' 'COUNT_RATE'
 'COUNT_RATE_ERR' 'EXPOSURE']
chips> xlo = get_colvals (cr, "time_min")
chips> xhi = get_colvals (cr, "time_max")
chips> y = get_colvals (cr, "count_rate")
chips> dy = get_colvals (cr, "count_rate_err")

If given two arrays then add_histogram will assume the X array refers to the mid-point of each bin. However, if given three arrays it uses the first two arrays to define the start and edge of each bin. The resulting figure is shown in Figure 12:

chips> clear()
chips> add_histogram (xlo, xhi, y)
[Thumbnail image: The bin edges are given by the user, rather than having to be calculated.]

[Version: full-size, PNG, postscript]

[Print media version: The bin edges are given by the user, rather than having to be calculated.]

Figure 12: A histogram of xlo,xhi,y values

This figure shows the histogram created by plotting up the TIME_MIN, TIME_MAX columns - which determine the bin edges - against the COUNT_RATE column.

The result is the same as Figure 8 - except for the axis labels - since for this data set the time bins all have the same width and are contiguous. This can be seen by overplotting the histogram calculated using the TIME values (see Figure 13).

chips> xmid = get_colvals (cr, "time")
chips> add_histogram (xmid, y, ["line.color","red"])
[Thumbnail image: The red histogram overlaps the previous histogram.]

[Version: full-size, PNG, postscript]

[Print media version: The red histogram overlaps the previous histogram.]

Figure 13: Comparing histograms

The red histogram - which represents the TIME,COUNT_RATE values - is the same as the one calculated from the TIME_MIN,TIME_MAX bin edges.

We could use undo to remove the second histogram, but we decide to delete it instead using delete_histogram.

chips> delete_histogram()
chips> set_histogram (["symbol.style","circle"])

The pick and get_pick routines can be used if you want to select a point or region in a plot. When called with no arguments, pick will report the location of the first click you make in the plot. During this time it may update the title of the ChIPS window with the current location of the mouse (this feature depends on the window manager being used). In the output below we selected a point near the peak of the light curve. The get_pick routine is used if you want the coordinates of the point, or points, returned as a set of Python variables.

chips> pick()
(7.74015e+07,14.7946)

Here we decide to restrict the X axis of the plot, mainly to remove the zero values at the start and end of the time series. The result is Figure 14.

chips> limits (X_AXIS, 7.739e+07, 7.7405e+07)
[Thumbnail image: The circles are added at the mid-point of each bin.]

[Version: full-size, PNG, postscript]

[Print media version: The circles are added at the mid-point of each bin.]

Figure 14: Adding symbols to histograms

Histograms can also be drawn using symbols.

The support for symbols is the same as for curves. Here we show how multiple values can be changed with a single call to set_histogram using the value returned by get_histogram. The result is Figure 15.

chips> log_scale (Y_AXIS)
chips> hi = get_histogram()
chips> hi.symbol.color = "red"
chips> hi.symbol.fill = 1
chips> hi.symbol.size = 3
chips> set_histogram (hi)
chips> save_state("sym-circle-fill.state")
[Thumbnail image: The circles are now red, filled, and smaller than before.]

[Version: full-size, PNG, postscript]

[Print media version: The circles are now red, filled, and smaller than before.]

Figure 15: Changing symbol properties

The symbols are now drawn as red, filled circles.

The ChIPS state file sym-circle-fill.state is included in chips_data.tar.gz and can be loaded by saying:

chips> load_state("sym-circle-fill.state")


Error bars

Error bars on the Y axis values, either symmetric or asymmetric, can be included in histograms. Here we add the errors on the count-rate measurements, which are quite small for this data set, as Figure 16 shows.

chips> clear()
chips> add_histogram (xlo, xhi, y, dy)
chips> limits (X_AXIS, 7.738e7, 7.739e7)
chips> limits (Y_AXIS, 0, 2)
[Thumbnail image: The symmetric error bars are drawn at the mid-point of each bin.]

[Version: full-size, PNG, postscript]

[Print media version: The symmetric error bars are drawn at the mid-point of each bin.]

Figure 16: Displaying error bars on a histogram

As with curves, histograms can display error bars, although only for the Y axis values.

The line can be removed, by setting the line.style attribute to none (Figure 17):

chips> set_histogram(["line.style","none"])
[Thumbnail image: The error bars are drawn but there is no line marking connnecting the bins.]

[Version: full-size, PNG, postscript]

[Print media version: The error bars are drawn but there is no line marking connnecting the bins.]

Figure 17: A histogram without lines

The line style can be set to none to remove the line that connects the bins.

Symbols can be added (here an open square), which creates Figure 18:

chips> set_histogram(["symbol.style","square"])
[Thumbnail image: An open square marks the mid-point of each bin.]

[Version: full-size, PNG, postscript]

[Print media version: An open square marks the mid-point of each bin.]

Figure 18: Symbols and error bars

An open square has been chosen to mark the mid-point of each bin.

Error bars can be added to histograms specified just using the mid-point of the bin, but you still have to supply two arguments for the low and high bin edges, but set the second one to None. First we create the data to plot; we chose those bins which have a positive count rate and convert the time values into an offset in kiloseconds. We use the Crates routine get_keyval to get the OBJECT keyword from the data set.

chips> i = y > 0
chips> x2 = (xmid[i] - xmid[0]) / 1e3
chips> y2 = y[i]
chips> dy2 = dy[i]
chips> obj = get_keyval (cr, "OBJECT")

Now we have the data we can plot it. The first argument to add_histogram is the bin center and the second argument is None , which means the histogram bins are taken to be centered at x2,y2.

chips> clear()
chips> add_histogram (x2, None, y2, dy2, [ "err.color", "red", "line.color", "blue" ])
chips> log_scale (Y_AXIS)
chips> set_plot_xlabel (r"\Delta t (ks)")
chips> set_plot_ylabel ("Rate (count s^{-1})")
chips> set_plot_title (obj)
chips> save_state("err-mid.state")
[Thumbnail image: The bins are marked with a blue line and the error bars colored red.]

[Version: full-size, PNG, postscript]

[Print media version: The bins are marked with a blue line and the error bars colored red.]

Figure 19: Error bars for xmid,y histograms

Colors have been added to show that the individual elements of a histogram can be colored separately.

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

chips> load_state("err-mid.state")


Zooming in on a histogram

In this section we will add a second plot to Figure 19, showing a zoomed-in region of the start of the light curve (before the flare). To make the most use of the space we will manually add the second plot so that it appears within the existing plot. We do this by calling add_plot to create the new plot and give it the coordinates to use for the bottom-left and top-right of the plot. The coordinate system used here is "frame normalized", where 0,0 is the bottom-left of the frame and 1,1 is the top-right of the frame. Note that undo, move_plot, and reposition_plot are useful commands when trying to get the plot in a good position. The result of the add_plot call is shown in Figure 20.

chips> add_plot (0.25,0.5,0.6,0.85, ["id","zoom"])
chips> print get_plot()
bottommargin = 0.5
corner.style = miter
id = None
leftmargin = 0.25
rightmargin = 0.399999976158
stem = None
style = closed
title.angle = 0.0
title.color = default
title.depth = 100
title.font = helvetica
title.fontstyle = normal
title.halign = 0.5
title.size = 16
title.valign = 0.5
title.xpos = 0.5
title.ypos = 15.0
topmargin = 0.149999976158

Note that the rightmargin and topmargin values are set to values of 1-xpos and 1-ypos, where xpos and ypos are the second pair of coordinates used in the add_plot call above (with some small rounding error).

[Thumbnail image: The second plot has been added within the first one, placed so as not to overlap the data.]

[Version: full-size, PNG, postscript]

[Print media version: The second plot has been added within the first one, placed so as not to overlap the data.]

Figure 20: Placing a plot within an existing plot

The second plot - shown as just the borders - is placed in the top-left corner of the first plot.

We decide that we do not want borders around the plot, so we change the plot style from closed to open. After the set_plot call, the plot is no longer visible (i.e. the result looks like Figure 19), but the plot still exists, as is shown by the output of info:

chips> set_plot (["style", "open"])
chips> print 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]
      Histogram [hist1]
    Plot [zoom]   (0.25,0.50)  .. (0.60,0.85)
      Border bottom [bx1]  top [bx2]  left [by1]  right [by2]

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

As the second plot is current, any new histogram will be added to it (and will automatically create axes, since the plot zoom does not contain any yet). We change the id from the default (which would be hist1) to make it clearer which objects are current in the output of info and info_current (and also to show that you can have different objects with the same id, in this case a plot and a histogram).

chips> add_histogram (x2, y2, ["id", "zoom"])
chips> print 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]
      Histogram [hist1]
    Plot [zoom]   (0.25,0.50)  .. (0.60,0.85)
      Border bottom [bx1]  top [bx2]  left [by1]  right [by2]
      X Axis [ax1]
      Y Axis [ay1]
      Histogram [zoom]

chips> print info_current()
Window [win1]
  Frame [frm1]
    Plot [zoom]
      X Axis [ax1]
      Y Axis [ay1]
      Histogram [zoom]
    Coord Sys [Data]
    Coord Sys ID [zoom_ax1ay1]

We zoom in on the region of interest, and make the histogram filled with the following three commands, to create Figure 21:

chips> limits (Y_AXIS, 0.4, 1.6)
chips> limits (X_AXIS, 1, 22)
chips> set_histogram (["fill.visible", 1])
[Thumbnail image: The second histogram shows a zoomed in version of the main plot.]

[Version: full-size, PNG, postscript]

[Print media version: The second histogram shows a zoomed in version of the main plot.]

Figure 21: Zooming in

The second plot shows the start of the lightcurve; since the flare is not included in this time period the Y-axis has been left using a linear scale.

Due to a bug in CIAO 4.0, the hardcopy versions (i.e. those created by print_window) of figures containing filled histograms and regions where the fill.color attribute is set to default actually use the foreground.display preference setting for the fill color rather than the foreground.file setting. The default value for this preference is white, so the PNG and postscript versions of this figure and Figure 22 do not appear to have a filled histogram. Explicitly setting the fill.color setting to black (or some other value) will work around this bug.

As the second histogram has been drawn filled, the X-axis tick marks are not visible in this plot. We could change the Y axis so that it starts at a negative value, such as -0.1, since the histogram fill extends down to y=0, but we decide to change the color of the axes from the default value to gray, and then shuffle the X axis so that it is drawn above all the other elements at its depth (so it will not be over-drawn by the histogram). Since an axis contains several color attributes - e.g. the axis itself, the major and minor tick marks, the label - we make use of the set_cascading_property call to change all the color settings at once. As no axis id was given, the changes are applied to both the X and Y axes, as these are both current (see the output of the info_current command above). The result is shown in Figure 22.

chips> set_cascading_property (chips_axis , "color", "gray")
chips> shuffle_axis ("ax1", chips_front)
chips> save_state("pip.state")
[Thumbnail image: The X-axis tick marks can be seen once again.]

[Version: full-size, PNG, postscript]

[Print media version: The X-axis tick marks can be seen once again.]

Figure 22: Re-displaying the X axis

Compare the axes in the second plot to those in Figure 21; the tick labels are now visible on the X axis and the axes are now drawn in gray (the color difference may be more visible in the PNG and postscript versions of the figure).

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

chips> load_state("pip.state")


Using two Y axes in a single plot

In this section we show how you can add an extra axis to a plot and use it to display a second set of data. This is different to the Customizing the axes section of the "symbol support in curves" thread, where a second axis was added for informational purposes.

Our aim is to plot up the count-rate histogram of lc.fits and overlay a curve showing the exposure time of each bin, which is stored in the EXPOSURE column of the file. We therefore get this column from the crate and filter it to remove non-zero times to create the array e2:

chips> etime = get_colvals (cr, "EXPOSURE")
chips> e2 = etime[i];

First we plot up the histogram, using as the X-axis values the offset in kiloseconds array (x2) created in the errors section above.

chips> clear()
chips> add_histogram (x2, y2)
chips> set_plot_xlabel (r"\Delta t (ks)")
chips> set_plot_ylabel ("Rate (count s^{-1})")

Now we add a second Y axis to the plot. We chose to position it at the right-hand edge of the plot, which means we can use the plot-normalized coordinate system and set the coordinate to 1. The minimum and maximum values for the new axis are set to 0 and 1 respectively; the values are not important as they will be changed when the exposure curve is added later. The result of these commands is Figure 23.

chips> id = ChipsId()
chips> id.coord_sys = PLOT_NORM
chips> add_axis (id, Y_AXIS, 1, 0, 1)
chips> print 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]
      Histogram [hist1]
      Y Axis [ay2]

chips> print info_current()
Window [win1]
  Frame [frm1]
    Plot [plot1]
      X Axis [ax1]
      Histogram [hist1]
      Y Axis [ay2]
    Coord Sys [Data]
    Coord Sys ID [plot1_ax1ay2]

[Thumbnail image: A second Y axis has been added to the right-hand edge of the plot.]

[Version: full-size, PNG, postscript]

[Print media version: A second Y axis has been added to the right-hand edge of the plot.]

Figure 23: Adding a second Y axis

The new Y axis has been added to the right-hand edge of the plot. Since it has been added in plot-normalized coordinates then it will move with the plot - as shown below when we increase the rightmargin attribute of the plot to create Figure 25 - but will not move if we change the X-axis limits of the plot.

The axes used to plot a curve or histogram (i.e. the data coordinate system that is used) is determined by the current pair of axes. The output of info_current above show that the current axes are the X axis and the second Y axis, so the add_curve call below will use them, as shown by the fact that the limits have been increased to cover the data (ie the maximum value is now close to 200 in Figure 24).

chips> add_curve (x2, e2)
chips> set_curve (["symbol.style", "none"])
chips> print info()
Window [win1]
  Frame [frm1]
    Plot [plot1]   (0.15,0.15)  .. (0.85,0.90)
      Border bottom [bx1]  top [bx2]  left [by1]  right [by2]
      X Axis [ax1]
      Y Axis [ay1]
      Histogram [hist1]
      Y Axis [ay2]
      Curve [crv1]

Note that we could have drawn a second histogram here - i.e. said add_histogram (x2,e2) instead - since the data is effectively binned, since it represents the exposure time within the bin. However we chose to use a curve to show that the two types (curve and histogram) can be included in the same plot.

[Thumbnail image: The time,exposure values have been added as a curve, using the Y axis on the right-hand side of the plot.]

[Version: full-size, PNG, postscript]

[Print media version: The time,exposure values have been added as a curve, using the Y axis on the right-hand side of the plot.]

Figure 24: Adding a curve using the new Y axis

The right-hand side Y axis is used to display the new data, and has automatically increased to cover the new data range (it actually uses the union of the old axis range of 0-1 and the range of y2 values which is why the result is roughly 0 to 200).

We change the exposure curve to use a dotted line style, so it does not distract from the histogram too much, and set the limits of the current Y axis - hence the one on the right-hand side of the plot - to span the range of the y2 array (which is roughly 40 to 200). Note that the axis used to display the histogram has not been changed by this call.

chips> set_curve (["line.style", "dot"])
chips> limits (Y_AXIS, AUTO, AUTO) 

In order to add a label to this axis we increase the rightmargin attribute of the plot from 0.1 to 0.15 and then add a label to the axis. The result is shown in Figure 25.

chips> print get_plot()
bottommargin = 0.15000000596
corner.style = miter
id = None
leftmargin = 0.15000000596
rightmargin = 0.10000000149
stem = None
style = closed
title.angle = 0.0
title.color = default
title.depth = 100
title.font = helvetica
title.fontstyle = normal
title.halign = 0.5
title.size = 16
title.valign = 0.5
title.xpos = 0.5
title.ypos = 15.0
topmargin = 0.10000000149

chips> set_plot (["rightmargin", 0.15])
chips> set_plot_ylabel ("Exposure per bin (s)")
[Thumbnail image: A label has been added to the new Y axis, after moving the right-hand edge of the plot to make space for it.]

[Version: full-size, PNG, postscript]

[Print media version: A label has been added to the new Y axis, after moving the right-hand edge of the plot to make space for it.]

Figure 25: Labelling the new Y axis

The right-hand margin of the plot has been increased in order to make space for the axis label of "Exposure per bin (s)".

There are many attributes controlling the appearance and behavior of an axis: below we show those relevant to the axis label and change the rotation and offset so that the text reads from the bottom to the top. The result of these commands is shown in Figure 26.

chips> print get_yaxis().label
angle = 270.0
color = default
font = helvetica
fontstyle = normal
halign = 0.5
size = 14
valign = 0.0
visible = True

chips> set_yaxis (["label.angle", 90])
chips> print get_yaxis().offset
parallel = 0.0
perpendicular = 40.0

chips> set_yaxis (["offset.perpendicular", 45])
[Thumbnail image: The label has been rotated by 180 degrees.]

[Version: full-size, PNG, postscript]

[Print media version: The label has been rotated by 180 degrees.]

Figure 26: Altering the label of the Y axis

The Y-axis label has been rotated so that it reads the same way as the original Y axis.

We can switch between the Y axes - and hence coordinate systems - using the current_axis call. Below we switch back to the original Y axis and change the limits to highlight the low-count rate region. The exposure curve is unaffected by this. We then change the curve and histogram to improve the visibility of the plot, creating Figure 27.

chips> current_axis ("ay1")
chips> print info_current()
Window [win1]
  Frame [frm1]
    Plot [plot1]
      X Axis [ax1]
      Y Axis [ay1]
      Histogram [hist1]
      Curve [crv1]
    Coord Sys [Data]
    Coord Sys ID [plot1_ax1ay1]

chips> limits (Y_AXIS, 0.3, 2)
chips> set_histogram (["fill.visible",1,"fill.color","skyblue"])
chips> set_curve (["line.color", "red", "line.thickness", 3])
chips> set_histogram (["depth", 50])
[Thumbnail image: The original y axis has been changed to display the range 0.3 to 2.]

[Version: full-size, PNG, postscript]

[Print media version: The original y axis has been changed to display the range 0.3 to 2.]

Figure 27: Switching back to the original Y axis

The y axis has been zoomed in from the original range of close to 0 to 15 to highlight theloiw count-rate region. Note that the exposure axis has not changed from that shown in Figure 26.

Since both the curve and the histogram share the same X axis, the following command zooms both data sets, and creates Figure 28.

chips> limits (X_AXIS, 3, 20)
chips> save_state("axis2-xzoom.state")
[Thumbnail image: Both the curve and the histogram have been changed to show the x axis range of 3 to 20.]

[Version: full-size, PNG, postscript]

[Print media version: Both the curve and the histogram have been changed to show the x axis range of 3 to 20.]

Figure 28: Changing the X-axis limits

As both coordinate systems - plot1_ax1ay1 which shows the count rate data and plot1_ax1ay2 which shows the exposure data - use the same X axis (ax1), changing the limits of this axis changes both the curve and histogram.

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

chips> load_state("axis2-xzoom.state")


Support for irregularly-spaced bins

The low and high edges of consecutive histogram bins do not have to match, nor do the bins have to have the same widths, as shown in Figure 29:

chips> clear()
chips> xlo = [1,3,5,9,11,14]
chips> xhi = [2,5,9,10,14,15]
chips> y = [1e4,6e4,-2e4,1.2e5,7e3,9e3]
chips> add_histogram (xlo,xhi,y)
[Thumbnail image: Histograms can be drawn with irregular bin widths.]

[Version: full-size, PNG, postscript]

[Print media version: Histograms can be drawn with irregular bin widths.]

Figure 29: Support for irregularly-binned data

The histogram bins do not need to be regularly spaced, and there can be gaps between bins. The Y values can also be zero or negative.

The normal attributes of a histogram work as expected with this data, as shown in Figure 30, where a number of attributes have been changed. We also change the format used for the tick labels on the Y axis.

chips> hi = ChipsHistogram()
chips> hi.fill.visible = 1
chips> hi.fill.color = "green"
chips> hi.line.color = "red"
chips> hi.symbol.style = "diamond"
chips> hi.symbol.fill = 1
chips> hi.symbol.color = "blue"
chips> hi.symbol.size = 7
chips> hi.dropline = 1
chips> set_histogram (hi)
chips> set_yaxis (["tickformat", "%.5Z"])
[Thumbnail image: The histogram is now drawn with a red line, blue symbols, and a green fill.]

[Version: full-size, PNG, postscript]

[Print media version: The histogram is now drawn with a red line, blue symbols, and a green fill.]

Figure 30: Changing many histogram attributes

The bins are filled down (or up) to the y=0 line, and marked by a symbol at the mid point of each bin. We make use of the ticklabel format support to use exponential notation for large values (an absolute value of 105 or greater).




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.