*! version 1.0 05may2026
help manybars

Title

manybars -- Bar graphs of a summary statistic for an outcome y variable at specific values of multiple indicator x variables

Syntax

manybars varname [if] [in], xvars(varlist) [stat(statistic)] [options]

options

Main options
xvars(varlist) Categorical indicator x variables. At least one xvar is required.

stat(statistic [, stat_options]) The summary statistic that will be calculated for varname

displayvalues(numlist) Optional values of the xvars at which stat will be calculated

overvars(varlist) Optional categorical variables for further grouping

nowarn Suppress warning messages about missing values

Graph options
horizontal Display the graph horizontally

graphopts(optional_graph_options) Options for the graph (but not for the legend)

addtolegend(optional_legend_options) Additional options for the graph legend

newlegend(optional_legend_options) Replacement options for the graph legend

varlabel Display variable labels for the xvars instead of the default display of value labels

Description

manybars generates bar graphs showing a summary statistic for an outcome variable, computed separately at user-specified values of one or more indicator variables. This adds functionality to Stata's native graph bar command, which requires a single categorical grouping variable for each over() call and cannot draw bars for multiple separate indicator variables in a single graph.

The command accepts one or more numeric indicator variables as x variables ("xvars") and computes the specified statistic (default: mean) of the outcome at a specific value of each indicator (default: 1), displaying the results as a grouped bar graph with legend labels drawn from value or variable labels. The displayvalues() option allows the user to specify which value of each xvar defines the subgroup of interest. Optionally, bars can be further grouped by one or more (usually categorical) grouping variables using the overvars() option. This produces clustered bar graphs that compare the statistic, at each xvar=displayvalue, across those over-variables.

The program will exit with an error if xvar=displayvalue has zero observations for any bar.

Options

Main Options

xvars(varlist) specifies one or more categorical explanatory variables for which the value(s) of the y-variable will be computed and graphed. xvars is required.

stat(statistic) allows the user to specify any of the following statistics to be graphed:

mean sd skew kurt min max count total median iqr mode mad mdev

Optional stat_options are any options for the underlying egen command used to generate the values of varname for display. These options are passed directly to egen without validation. Do not include by() within stat_options, as it will return an error. Use the overvars() option instead.

displayvalues(numlist) optionally specifies the values of the xvars at which the requested stat will be calculated.

If displayvalues are not specified, the default value of 1 will be used for each xvar.

If a single displayvalue is specified, that value will be used for each xvar.

Alternatively, users may specify a number of displayvalues equal to the number of xvars. In this case, the first displayvalue will be used for the first variable, the second value will be used for the second variable, and so on. If the number of supplied values does not equal the number of variables, an error will be returned.

overvars(varlist) are optional additional categorical variables over which the stat will be graphed at each level of the xvars, similar to many commands' by, within, and over options. Note that, unlike graph bar's native repeatable over() option, in manybars all grouping variables are listed in a single list of overvars. graph bar's over_suboptions are not supported.

The nowarn option suppresses warning messages about missing values on the yvar, xvars, and overvars that are displayed by default. Only observations with complete data on the relevant variables are included in the graph. nowarn does not prevent the program from exiting if there is an error.

Note: graph bar and graph hbar do not differentiate between bars with zero height (i.e., there are valid observations but they all equal zero) from bars that are not drawn because the entire bar is missing (i.e., all observations for xvar=displayvalue are missing). One way to graph the difference is to add blabel(bar) to graphopts().

Graph and Legend Options

The horizontal option changes the graph call to graph hbar. If horizontal is not specified, the graph call will be graph bar.

graphopts() are passed as-is to graph bar.

addtolegend() allows any of graph bar's legend_options to be added to manybars's default legend() call. Do not include "legend()" within addtolegend(), as it will return an error.

newlegend() may not be combined with addtolegend(). newlegend() completely replaces manybars's default legend, starting over from graph bar, legend(legend_options). Do not include "legend()" within newlegend(), as it will return an error.

By default, the graph legend will display the applicable value label for the displayvalue of each xvar. Option varlabel requests that the xvar variable name(s) be displayed instead.

Examples

Basic syntax

sysuse nlsw88

Vertical graph: manybars wage, xvars(union collgrad)

Horizontal graph: manybars wage, xvars(union collgrad) horizontal

Specifying displayvalues

sysuse nlsw88

Same value for all xvars: manybars tenure, xvar(c_city never_married collgrad) displayvalues(0)

Specifying each value: manybars tenure, xvar(c_city never_married collgrad) displayvalues(1 1 0)

Graphing more than one level of the same xvar: manybars tenure, xvar(c_city never_married collgrad collgrad) displayvalues(1 1 0 1)

Modifying the graph and the legend

sysuse nlsw88

Adding graphopts: manybars wage, xvars(union collgrad) graphopts(bargap(11) ti(Great Graph!))

Adding to the legend with addtolegend: manybars wage, xvars(union collgrad) graphopts(bargap(11) ti(Great Graph!)) addtolegend(pos(6))

Replacing the legend with newlegend: `"manybars wage, xvars(union collgrad) graphopts(bargap(11) ti(Great Graph!)) newlegend(label(1 "Union Member") label(2 "Bachelor's Degree or Higher") pos(6) region(lc(pink)))"'

Addressing uninformative bars and legend labels

webuse lbw

Zero bar heights: manybars ftv, stat(median) xvar(smoke ptl) d(0)

Improved with blabel: manybars ftv, stat(median) xvar(smoke ptl) d(0) graph(blab(bar, size(large)))

Better legend with varlabel: manybars ftv, stat(median) xvar(smoke ptl) d(0) graph(blab(bar, size(large))) varlabel

Grouping bars with overvars

webuse lbw

One overvar: manybars lwt, xvar(ht ptl) over(smoke) varlabel

Two overvars: manybars lwt, xvar(ht ptl) over(smoke race) varlabel addtolegend(pos(6))

Specifying options for the egen command with stat_options (see help egen)

sysuse nlsw88

No stat_option: manybars grade, stat(mode) xv(married) overvar(race union) graph(blab(bar) name(g_mode, replace) ti(stat: mode))

Using a stat_option: mode, maxmode"))"'

Comparison: graph combine g_mode g_max, ycom

Stored Results

manybars saves the following in r():

Scalars:

r(N_graphed) the sample size used in the graph

r(N_missing) the number of missing observations excluded from the graph due to missingness

r(n_xvars) the number of xvars

Macros:

r(yvar) the y variable

r(xvars) the x variable(s)

r(overvars) the over variable(s)

r(stat) the statistic calculated for the y variable

r(cmd) manybars

Author

Brian Shaw, Indiana University, USA

bpshaw@iu.edu