*! Help file for hist_overlay.ado version 1.32 22Mar2023 updated 17Apr2024

Title

hist_overlay -- Overlay one histogram on another,
so both are visible

Syntax

hist_overlay
xvar
[if] [in]
,
over(varname)
[
optional_options
]

Options

Required -option-
over(varname) The two overlaid histograms are constructed for the
two discrete values of this variable.

Optional -options-
bin(#) set number of bins to #, a positive integer. Applies to both histograms.

width(#) set width of bins to #, a positive real value. Applies to both histograms.

start(#) set lower limit of leftmost bin to #, any real value.

color1(colorstyle) this option and its pair, color2(colorstyle),
give the user optional control over the color and, in Stata 15, the opacity
of the two histograms. See colorstyle.
The default colors in Stata 15 for the two values of the over(varname)
are navy%50 and red%50 respectively. When they are overlaid, the color is purple.

xline1(real,line_opts) this option and its pair, xline2(real),
allow the user to specify that a vertical line be constructed using the same color
used to display one or the other of the two histograms.
The available line_opts are those that modify the rendition of the line
and are documented here.
The default colors in Stata 15 for the two values of the over(varname)
are navy and red respectively.
These options can be combined with the official Stata
option xline.

xlog Construct the histogram on the log10 transformation of xvar

powers Display x-axis labels as powers of 10. Only useful with
the option xlog.

plusone Add 1.0 to xvar before transforming it with the log10
transformation. Only useful with the option xlog.

verbose Provides additional output on the construction of the histogram bins.

Official histogram -options-
title(tinfo) overall title

subtitle(tinfo) subtitle of title

frequency draw as frequencies (default). With two overlaid histograms
the frequency option produces the most unambiguous graph.

fraction draw as fractions. The fractions add to 1.0 for
each of the two histograms, separately.

density draw as density. The density integrates to 1.0 for
each of the two histograms, separately.

addlabels add height labels to bars

addlabopts(label_options) affect rendition of labels.
See marker label options

* All other options are passed to histogram

Description

hist_overlay exploits Stata's twoway__histogram_gen command
to construct two histograms and then overlays one of them on top of the other
such that both are visible and can be distinguished from one another.
By experimenting with the options
bin(#)
width(#)
start(#) and
barwidth(#) and with the options
color1(colorstyle)
color2(colorstyle),
the user can find the look that is most appealing. The other official Stata
barlook_options are also available, but are not specific to one or
the other of the two histograms. They apply to both sets of bars.

UCLA Statistical Consulting Group's website presents a simple approach to overlaying histograms
here.
(accessed 21May, 2022)

Examples

The DO-file, example_hist_overlay.do,
available from CGD's Stata repository here,
contains the code to run the following
examples. First, clear memory and load Stata's
auto example data.

. clear

. sysuse auto
(1978 Automobile Data)

Using Stata's official histogram command, construct a histogram of the variable mpg.

. * Without options, the histogram of the variable mpg is:
. histogram mpg, frequency name(hist1, replace)
(bin=8, start=12, width=3.625)

.
. * The data contains a dichotomous variable -foreign-
. tab foreign, sum(mpg)

| Summary of Mileage (mpg)
Car type | Mean Std. Dev. Freq.

+

Domestic | 19.826923 4.7432972 52
Foreign | 24.772727 6.6111869 22

+

Total | 21.297297 5.7855032 74

.
. * Overlay the histograms of mpg for domestic and foreign cars
. * The -verbose- option gives detailed summary statistics
. * for both values of the variable -foreign- and shows
. * details on the construction of the histogram bars or "bins".
. hist_overlay mpg, frequency over(foreign) verbose name(hist2,replace)

For the first value of the variable foreign, the summary statistics are:

sum mpg if touse & foreign==0, det

Mileage (mpg)

Percentiles Smallest
1% 12 12
5% 14 12
10% 14 14 Obs 52
25% 16.5 14 Sum of Wgt. 52

50% 19 Mean 19.82692
Largest Std. Dev. 4.743297
75% 22 28
90% 26 29 Variance 22.49887
95% 29 30 Skewness .7712432
99% 34 34 Kurtosis 3.441459
(bin=7, start=12, width=3.1428571)

For the second value of the variable foreign, the summary statistics are:

sum mpg if touse & foreign==1, det

Mileage (mpg)

Percentiles Smallest
1% 14 14
5% 17 17
10% 17 17 Obs 22
25% 21 18 Sum of Wgt. 22

50% 24.5 Mean 24.77273
Largest Std. Dev. 6.611187
75% 28 31
90% 35 35 Variance 43.70779
95% 35 35 Skewness .657329
99% 41 41 Kurtosis 3.10734
(bin=10, start=12, width=3.1428571)

The bins and their contents are:

+
-
-
-
+
| BinHeight BinCenter BinHeight BinCenter |
+
-
-
-
+
1. | 9 13.57143 1 13.57143 |
2. | 13 16.71428 4 16.71428 |
3. | 14 19.85714 2 19.85714 |
4. | 8 23 4 23 |
5. | 3 26.14286 5 26.14286 |
+
-
-
-
+
6. | 4 29.28572 2 29.28572 |
7. | 1 32.42857 1 32.42857 |
8. | . 12 2 35.57143 |
9. | . . 1 41.85714 |
10. | . . . 12 |
+
-
-
-
+

.
. * Compare the two histograms side by side
. graph combine hist1 hist2, ycommon name(no_options, replace)

.
. * To make it easier to compare the two depictions of the data,
. * specify common starting points, widths and styles for the bars
. * and similarly formatted legends.
. histogram mpg, frequency start(10) width(2.5) fcolor(none) lcolor(black) legend(on order(1 "All cars") rows(1)) name(hist1, replace)
(bin=13, start=10, width=2.5)

.
. hist_overlay mpg, over(foreign) frequency start(10) width(2.5) name(hist2, replace)

.
. * Compare them side by side
. * The histograms now resemble one another.
. graph combine hist1 hist2, ycommon name(no_lbls, replace)

.
.
. * Add labels to make it easier to read the height of the bars
. histogram mpg, frequency start(10) width(2.5) fcolor(none) lcolor(black) legend(on order(1 "All cars") rows(1)) addlabels name(hist1, replace)
(bin=13, start=10, width=2.5)

.
. hist_overlay mpg, over(foreign) frequency start(10) width(2.5) addlabels name(hist2, replace)

.
. * Compare them side by side
. * Note that the heights of the two overlaid bars on the right
. * sum to the height of the corresponding bar on the left.
. graph combine hist1 hist2, ycommon name(withlbls, replace)

.
. * It's apparent from the overlaid histogram that foreign cars
. * achieve higher mileage. To emphasize this, add a vertical line
. * at the means of the distributions
.
. * Compute the overall mean
. sum mpg

Variable | Obs Mean Std. Dev. Min Max

+

mpg | 74 21.2973 5.785503 12 41

. local mpgall = `r(mean)'

. local mpgalltxt : di %9.1f `mpgall'

.
. * Compute mean for domestic cars
. sum mpg if foreign==0

Variable | Obs Mean Std. Dev. Min Max

+

mpg | 52 19.82692 4.743297 12 34

. local mpgdom = `r(mean)'

. local mpgdomtxt : di %4.1f `mpgdom'

.
. * Compute mean for foreign cars
. sum mpg if foreign==1, meanonly

. local mpgfor = `r(mean)'

. local mpgfortxt : di %4.1f `mpgfor'

.
. * Add a vertical line to mark the overall mean and label the line
. histogram mpg, frequency start(10) width(2.5) fcolor(none) lcolor(black) ///
> legend(on order(1 "All cars") rows(1)) addlabels ///
> xline(`mpgall',lcolor(black) lwidth(thick)) ///
> text(18 `mpgall' "Overall" "`mpgalltxt' mpg", orientation(vertical)) ///
> yscale(range(0 20)) name(hist1, replace)
(bin=13, start=10, width=2.5)

.
. * Add a vertical line to mark each of the two means and label them
. hist_overlay mpg, over(foreign) frequency start(10) width(2.5) addlabels ///
> xline1(`mpgdom', lwidth(thick)) xline2(`mpgfor', lwidth(thick)) ///
> text(18 `mpgdom' "Domestic" "`mpgdomtxt' mpg", orientation(vertical)) ///
> text(18 `mpgfor' "Foreign" "`mpgfortxt' mpg", orientation(vertical)) ///
> yscale(range(0 20)) name(hist2, replace)

.
. * Compare the two histograms, this time on top of one another
. graph combine hist1 hist2, ycommon col(1) name(withlines, replace)

.
. * For variables with right-skewed distributions, like -displacement- in this data,
. * the option -xlog- plots the two histograms with respect to the log
. * of the variable being analyzed. The bars are the same width
. * as measured by the logarithm of the analyss variable, here -displacement-.
. hist_overlay displacement, over(foreign) frequency addlabels xlog name(withxlog, replace)

Returned results

The program returns the following results:

macros:
r(barwidth) Width of the bars
r(start) Starting value of the first bar

matrices:
r(bindata) Data on the heights and centers of both sets of bars

Author

Mead Over, Senior Fellow, Center for Global Development

Email: MOver@CGDev.Org if you observe any problems.