|
Note: This FAQ is relevant for users of releases prior to
Stata 10.
How can I get “nice” time-of-day labels on a graph?
|
Title
|
|
Getting nice time-of-day labels on a graph
|
|
Author
|
Nicholas J. Cox, Durham University, UK
|
|
Date
|
February 2003, revised September 2003
|
The problem
If you are graphing data in Stata against time of day, one of your axes will
show time. For all but the crudest exploratory graphics, good labeling of
that axis is important. Tastes and conventions may vary, but many people
like to show times for whole hours and in the form 12:00. Sometimes people
like to distinguish times that are a.m. and times that are p.m. These may
be called "nice" or "round" labels and go beyond what may be achieved by
using format.
A companion FAQ addresses the question of date labels for daily dates: How
can I get “nice” date labels on a graph?
http://www.stata.com/support/faqs/graphics/date-labels.
The main trick suggested here is to use
foreach to define value labels including the required text. A detailed
tutorial on this command is given in Cox (2002). For labels, see
[D] label.
In what follows, we assume that time goes on the x axis. If you put
time on the y axis, you just need to think in terms of the
corresponding options; that is, for xlabel, read ylabel, and
so forth. We also assume that time is measured on a scale running from 0
(usually midnight) to, or almost to, 24 (usually also midnight). If your
time origin is not midnight, you will need to modify the methods here.
The main solution
Let’s first suppose that you want labels for your variable timeofday
to be in steps of three hours from midnight to midnight in the form 9:00 or
15:00. We type
. foreach t of num 0(3)24 {
. label def tod `t' "`t':00", modify
. }
. label val timeofday tod
. graph whatever timeofday, options xla(0(3)24, valuelabel)
Users of Stata 7 should not specify , valuelabel.
(When we type graph whatever,
we naturally presume that you will replace that with something appropriate to
your problem, such as graph twoway line temperature,
or even line temperature.)
Now to explain the trickery: given the
numlist 0(3)24, the value label for 0 is defined as
"0:00", for 3 as "3:00", and so forth. Then these value
labels are attached to our timeofday variable. Given a request to
show those numbers as xlabels on a graph on which
timeofday is shown on the x axis, Stata automatically uses
attached value labels instead.
As you may know, the entity (here t) controlling the
foreach loop is a local macro; inside the loop, its
contents are referenced by `t'.
Next suppose that you want labels for your variable timeofday to be
in a.m. or p.m. form, such as "9 a.m.". If only a few labels are
required, defining them directly may be easiest:
. label def tod 0 "12 a.m." 6 "6 a.m." 12 "12 p.m." 18 "6 p.m." 24 "12 a.m."
. label val timeofday tod
. graph whatever timeofday, options xla(0(6)24, valuelabel)
Naturally, you may prefer some other convention for showing midnight or
noon. There is no problem if the same label is used for different integers.
If we wanted to do this in a loop, the boundary cases may need special care,
so much so that typing out definitions one by one is attractive by
comparison:
. foreach t of num 0(3)24 {
. local T = mod(`t',12)
. local T = cond(`T' == 0, 12, `T')
. local txt = cond(`t' < 12 | `t' == 24, "a.m.", "p.m.")
. label def tod `t' "`T' `txt'", modify
. }
. label val timeofday tod
. graph whatever timeofday, options xla(0(3)24, valuelabel)
The functions mod() and cond() used here are explained in [D]
functions. For further discussion, see Cox (2002).
Another solution
Another solution is naturally just to supply labels on the fly:
. graph whatever timeofday, options xla(0 "12 a.m." 6 "6 a.m."
> 12 "12 p.m." 18 "6 p.m." 24 "12 a.m.")
That has some marked advantages and disadvantages. For a graph not to be
repeated, it will be fast and direct. Moreover, if you want for some reason
to show a label for a time such as 12:45 p.m., and time is measured in
hours, then you can include 12.75 "12:45 p.m.", which you cannot do
by value labels as 12.75 is not an integer. (12.75 is not a typo, as a
moment’s thought will make clear.) On the other hand, typing such
details repeatedly could be tedious, although there are other ways of
avoiding that.
References
- Cox, N. J. 2002.
- Speaking Stata: How to face lists with fortitude.
Stata Journal
2: 202–222.
- ——. 2002.
- Speaking Stata: On getting functions to do the work.
Stata Journal
2: 411–427.
|