Title | Getting nice time-of-day labels on a graph | |

Author | Nicholas J. Cox, Durham University, UK |

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?.

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.

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

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 **xlabel**s 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:

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:

The functions **mod()** and **cond()** used here are explained in the
**[F] Functions Reference Manual**. For further discussion, see Cox (2002).

Another solution is naturally just to supply labels on the fly:

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.

- 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.