Displaying Date/Time Data on Axis Objects
Dates and times are among the many types of information that numerical data can represent. IDL provides a number of routines that offer specialized support for generating, analyzing, and displaying date- and time- based data (herein referred to as date/time data). For information on Julian dates and times, the Precision of Date/Time data, and information on how to generate Date/Time data, see Date/Time Data (Application Programming).
You can display date/time data on plots, contours, and surfaces through the tick settings of the date/time axis. Date/time data can be displayed on any axis (x, y or z). The date/time data is stored as Julian dates, but the LABEL_DATE routine and axis keywords allow you to display this data as calendar dates. The following examples show how to display one-dimensional and two-dimensional date/time data:
Displaying Date/Time Data on a Plot Display
Date/time data usually comes from measuring data values at specific times. For example, the displacement (in inches) of an object might be recorded at every second for 37 seconds after the initial recording of 59 minutes and 30 seconds after 2 o'clock pm (14 hundred hours) on the 30th day of March in the year 2000 as follows
number_samples = 37 date_time = TIMEGEN(number_samples, UNITS = 'Seconds', $ START = JULDAY(3, 30, 2000, 14, 59, 30)) displacement = SIN(10.*!DTOR*FINDGEN(number_samples))
Normally, this type of data would be imported into IDL from a data file. However, this section is designed specifically to show how to display date/time data, not how to import data from a file; therefore, the data for this example is created with the above IDL commands.
Before displaying this one-dimensional data with the IDLgrPlot object, the format of the date/time values is specified through the LABEL_DATE routine:
where %I represents minutes and %S represents seconds.
Before applying the results from LABEL_DATE, we must first create (initialize) our display objects:
oPlotWindow = OBJ_NEW('IDLgrWindow', RETAIN = 2, $
DIMENSIONS = [800, 600])
oPlotView = OBJ_NEW('IDLgrView', /DOUBLE)
oPlotModel = OBJ_NEW('IDLgrModel')
oPlot = OBJ_NEW('IDLgrPlot', date_time, displacement, $
/DOUBLE)
The oPlotModel object will contain the IDLgrPlot and IDLgrAxis objects. The oPlotView object contains the oPlotModel object with the DOUBLE keyword. The DOUBLE keyword is set for the oPlotView and oPlot objects because the date/time data is made up of double-precision floating-point values.
Although the date/time part of the data will actually be contained and displayed through the IDLgrAxis object, the oPlot object is created first to provide a display region for the axes:
oPlot->GetProperty, XRANGE = xr, YRANGE = yr xs = NORM_COORD(xr) xs[0] = xs[0] - 0.5 ys = NORM_COORD(yr) ys[0] = ys[0] - 0.5 oPlot->SetProperty, XCOORD_CONV = xs, YCOORD_CONV = ys
The NORM_COORD routine is used to create a normalized (0 to 1) display coordinate system. This coordinate system will also apply to the IDLgrAxis objects:
; X-axis title. oTextXAxis = OBJ_NEW('IDLgrText', 'Time (seconds)') ; X-axis (date/time axis). oPlotXAxis = OBJ_NEW('IDLgrAxis', 0, /EXACT, RANGE = xr, $ XCOORD_CONV = xs, YCOORD_CONV = ys, TITLE = oTextXAxis, $ LOCATION = [xr[0], yr[0]], TICKDIR = 0, $ TICKLEN = (0.02*(yr[1] - yr[0])), $ TICKFORMAT = ['LABEL_DATE'], TICKINTERVAL = 5, $ TICKUNITS = ['Time']) ; Y-axis title. oTextYAxis = OBJ_NEW('IDLgrText', 'Displacement (inches)') ; Y-axis. oPlotYAxis = OBJ_NEW('IDLgrAxis', 1, /EXACT, RANGE = yr, $ XCOORD_CONV = xs, YCOORD_CONV = ys, TITLE = oTextYAxis, $ LOCATION = [xr[0], yr[0]], TICKDIR = 0, $ TICKLEN = (0.02*(xr[1] - xr[0]))) ; Plot title. oPlotText = OBJ_NEW('IDLgrText', 'Measured Signal', $ LOCATIONS = [(xr[0] + xr[1])/2., $ (yr[1] + (0.02*(yr[0] + yr[1])))], $ XCOORD_CONV = xs, YCOORD_CONV = ys, $ ALIGNMENT = 0.5)
The TICKFORMAT, TICKINTERVAL, and TICKUNITS keywords specify the X-axis as a date/time axis.
These objects are now added to the oPlotModel object and this model is added to the oPlotView object:
oPlotModel->Add, oPlot oPlotModel->Add, oPlotXAxis oPlotModel->Add, oPlotYAxis oPlotModel->Add, oPlotText oPlotView->Add, oPlotModel
Now the oPlotView object, which contains all of these objects, can be viewed in the oPlotWindow object:
The Draw method to the oPlotWindow object produces the following results:
The above display shows the progression of the date/time variable, but it does not include all of the date/time data we generated with the TIMEGEN routine. This data also includes hour, month, day, and year information. IDL can display this information with additional levels to the date/time axis. You can control the number of levels to draw and the units used at each level with the TICKUNITS keyword. You can specify the formatting for these levels by changing the DATE_FORMAT keyword setting to the LABEL_DATE routine:
where %H represents hours, %D represents days, %M represents months, and %Y represents years. Notice DATE_FORMAT is specified with a three-element vector. Date/time data can be displayed on an axis with three levels. The format of these levels are specified through this vector.
In this example, the first level (closest to the axis) will contain minute and second values separated by a colon (%I:%S). The second level (just below the first level) will contain the hour values (%H). The third level (the final level farthest from the axis) will contain the day and month values separated by a space and year value separated from the day and month values by a comma (%D %M, %Y). For more information, see LABEL_DATE.
Besides the above change to the LABEL_DATE routine, we must also change the settings of the IDLgrAxis properties to specify a multiple level axis:
oPlotXAxis->SetProperty, $ TICKFORMAT = ['LABEL_DATE', 'LABEL_DATE', 'LABEL_DATE'], $ TICKUNITS = ['Time', 'Hour', 'Day']
The TICKFORMAT is now set to a string array containing an element for each level of the axis. The TICKUNITS keyword is set to note the unit of each level. These property settings produce the following results:
Notice the three levels of the X-axis. These levels are arranged as specified by the previous call to the LABEL_DATE routine.
To maintain IDL's memory, the object references for oPlotView, oTextXAxis, and oTextYAxis should be destroyed. Therefore, after the display is drawn, the OBJ_DESTROY routine should be called:
The display will remain until closed, but the object references are now freed from IDL's memory.
Displaying Date/Time Data on a Contour Display
Another possible example may be the surface temperature (in degrees Celsius) of each degree of a single circle on a sphere recorded at every second for 37 seconds after the initial recording of 59 minutes and 30 seconds after 2 o'clock pm (14 hundred hours) on the 30th day of March in the year 2000:
number_samples = 37 date_time = TIMEGEN(number_samples, UNITS = 'Seconds', $ START = JULDAY(3, 30, 2000, 14, 59, 30)) angle = 10.*FINDGEN(number_samples) temperature = BYTSCL(SIN(10.*!DTOR* $ FINDGEN(number_samples)) # COS(!DTOR*angle))
As with the one-dimensional case, the format of the date/time values is specified through the LABEL_DATE routine as follows:
where %I represents minutes, %S represents seconds, %H represents hours, %D represents days, %M represents months, and %Y represents years.
The first level (closest to the axis) will contain minute and second values separated by a colon (%I:%S). The second level (just below the first level) will contain the hour values(%H). The third level (the final level farthest from the axis) will contain the day and month values separated by a space and year value separated from the day and month values by a comma (%D %M, %Y).
Since the final contour display will be filled, we should define a color palette:
As in the one-dimensional example, the display must be initialized:
oContourWindow = OBJ_NEW('IDLgrWindow', RETAIN = 2, $
DIMENSIONS = [800, 600])
oContourView = OBJ_NEW('IDLgrView', /DOUBLE)
oContourModel = OBJ_NEW('IDLgrModel')
oContour = OBJ_NEW('IDLgrContour', temperature, $
GEOMX = angle, GEOMY = date_time, GEOMZ = 0., $
/PLANAR, /FILL, PALETTE = oContourPalette, $
/DOUBLE_GEOM, C_VALUE = BYTSCL(INDGEN(8)), $
C_COLOR = BYTSCL(INDGEN(8)))
; Applying contour lines over the original contour display.
oContourLines = OBJ_NEW('IDLgrContour', temperature, $
GEOMX = angle, GEOMY = date_time, GEOMZ = 0.001, $
/PLANAR, /DOUBLE_GEOM, C_VALUE = BYTSCL(INDGEN(8)))
The oContourModel object will contain the IDLgrContour and IDLgrAxis objects. The oContourView object contains the oContourModel with the DOUBLE keyword. The DOUBLE and DOUBLE_GEOM keywords are set for the oContourView and oContour objects because date/time data is made up of double-precision floating-point values.
Although the date/time part of the data will actually be contained and displayed through the IDLgrAxis object, the oContour object is created first to provide a display region for the axes:
oContour->GetProperty, XRANGE = xr, YRANGE = yr, ZRange = zr xs = NORM_COORD(xr) xs[0] = xs[0] - 0.5 ys = NORM_COORD(yr) ys[0] = ys[0] - 0.5 oContour->SetProperty, XCOORD_CONV = xs, YCOORD_CONV = ys oContourLines->SetProperty, XCOORD_CONV = xs, YCOORD_CONV = ys
The oContourLines object is created to display contour lines over the filled contours. Note these lines have a GEOMZ difference of 0.001 from the filled contours. This difference is provided to display the lines over the filled contours and not in the same view plane. The NORM_COORD routine is used to create a normalized (0 to 1) display coordinate system. This coordinate system will also apply to the IDLgrAxis objects:
; X-axis title. oTextXAxis = OBJ_NEW('IDLgrText', 'Angle (degrees)') ; X-axis. oContourXAxis = OBJ_NEW('IDLgrAxis', 0, /EXACT, RANGE = xr, $ XCOORD_CONV = xs, YCOORD_CONV = ys, TITLE = oTextXAxis, $ LOCATION = [xr[0], yr[0], zr[0] + 0.001], TICKDIR = 0, $ TICKLEN = (0.02*(yr[1] - yr[0]))) ; Y-axis title. oTextYAxis = OBJ_NEW('IDLgrText', 'Time (seconds)') ; Y-axis (date/time axis). oContourYAxis = OBJ_NEW('IDLgrAxis', 1, /EXACT, RANGE = yr, $ XCOORD_CONV = xs, YCOORD_CONV = ys, TITLE = oTextYAxis, $ LOCATION = [xr[0], yr[0], zr[0] + 0.001], TICKDIR = 0, $ TICKLEN = (0.02*(xr[1] - xr[0])), $ TICKFORMAT = ['LABEL_DATE', 'LABEL_DATE', 'LABEL_DATE'], $ TICKUNITS = ['Time', 'Hour', 'Day'], $ TICKLAYOUT = 2) oContourText = OBJ_NEW('IDLgrText', $ 'Measured Temperature (degrees Celsius)', $ LOCATIONS = [(xr[0] + xr[1])/2., $ (yr[1] + (0.02*(yr[0] + yr[1])))], $ XCOORD_CONV = xs, YCOORD_CONV = ys, $ ALIGNMENT = 0.5)
The TICKFORMAT, TICKINTERVAL, and TICKUNITS keywords specify the Y-axis as a date/time axis, which contains three levels related to the formats presented in the call to the LABEL_DATE routine. This example also contains the TICKLAYOUT keyword. By default, this keyword is set to 0, which provides the date/time layout shown in the plot example. In this example, TICKLAYOUT is set to 2, which rotates and boxes the tick labels.
These objects are now added to the oContourModel object and this model is added to the oContourView object:
oContourModel->Add, oContour oContourModel->Add, oContourLines oContourModel->Add, oContourXAxis oContourModel->Add, oContourYAxis oContourModel->Add, oContourText oContourView->Add, oContourModel
Now the oContourView object, which contains all of these objects, can be viewed in the oContourWindow object:
The Draw method to oContourWindow produces the following results:
Notice the three levels of the Y-axis. These levels are arranged as specified by the previous call to the LABEL_DATE routine.
To maintain IDL's memory, the object references for oContourView, oContourPalette, oTextXAxis, and oTextYAxis should be destroyed. Therefore, after the display is drawn, the OBJ_DESTROY routine should be called:
The display will remain until closed, but the object references are now freed from IDL's memory.


