*! opplot.sthlp version 1.04 - Biostat Global Consulting - 2024-01-04

Title

opplot -- Make an Organ Pipe Plot

Syntax

opplot yvar [if] [in] , CLUSTVAR(varname) [
STRATVAR(varname)
STRATUM(string)
WEIGHTvar(varname)
BARCOLOR1(string)
BARCOLOR2(string)
LINECOLOR1(string)
LINECOLOR2(string)
EQUALWIDTH
SAVEDATA(string)
EXPORTSTRAtumname
EXPORT(string)
EXPORTWidth(integer)
TWOWAY(string)
TITLE(string)
SUBtitle(string)
FOOTnote(string)
NOTE(string)
XTITLE(string)
YTITLE(string)
XLABEL(string)
YLABEL(string)
SAVING(string)
NAME(string)
XSIZE(real)
YSIZE(real)
PLOTN
NLINEColor(string)
NLINEWidth(string)
NLINEPattern(string)
YTITLE2(string)
YROUND2(integer 5)
LCTHRESHold(integer 999)
BARCOLORHIGH1(string)
BARCOLORMID1(string)
BARCOLORLOW1(string)
BARCOLORHIGH2(string)
BARCOLORMID2(string)
BARCOLORLOW2(string)
LINECOLORHIGH1(string)
LINECOLORMID1(string)
LINECOLORLOW1(string)
LINECOLORHIGH2(string)
LINECOLORMID2(string)
LINECOLORLOW2(string)
FOOTNOTECOVG
FOOTNOTEDEFF
FOOTNOTEICC
STRATUMNAME(string)
HIGH(integer 100)]

Description

opplot generates a vertical bar chart to summarize a binary outcome
in cluster survey data. The plot is known as an
organ pipe plot. Each cluster is represented with a vertical bar.
The shaded portion of the bar represents the proportion of respondents in
that cluster whose value of yvar is 1. Clusters with the highest
proportion of 1's (also known as coverage) are shown at the left side
of the plot. Coverage decreases monotonically from left to right.

If the data are self-weighting then the shaded proportion of the plot
is equal to the sample coverage. If the data are weighted
then the user should specify the WEIGHTvar, and the shaded
portion of the plot will represent the weighted sample coverage. If the
user specifies the WEIGHTvar then the width of each bar represents the
weighted proportion of the population represented by each cluster.

Organ pipe plots have some features in common with Pareto Charts from
the field of quality control.

Organ pipe plots were developed for the field of vaccination coverage
surveys, but they can be helpful for any type of cluster survey with binary
outcomes. The plots are useful for understanding the heterogeneity in
cluster-level coverage, which is related to the intracluster correlation
coefficient. The plots are also useful for identifying clusters with
surprisingly low or surprisingly high coverage.

Because the width of the bars can vary substantially, organ pipe plots
typically do not label the columns. If the viewer wants to identify
which bar represents which clusters, they consult an accompanying data
table which is (optionally) produced by this command.

Required Inputs

yvar - Binary variable which takes on only values of 0, 1 or missing (.).
This is the variable whose coverage the program estimates. As far as
opplot is concerned, a missing value is the same as a 0; neither
respondent has evidence of the outcome. All respondents are included in
the denominator and only those whose value of yvar==1 are included in
the numerator.

CLUSTVAR(varname) - Variable that holds the cluster ID.

Optional Inputs

STRATVAR(varname) - opplot is meant to show data for one stratum per plot.
If the dataset holds data for more than one stratum, specify the name of
the stratum ID variable and use the stratum option to specify
which stratum to plot.

STRATUM(string) - The value of stratvar for which to make the plot. E.g.,
if you want to plot coverage in stratum 14, specify stratum(14).

STRATUMNAME(string) - The name of the stratum that will be added as a note to the dataset. Name should correspond with the value provided in stratum

WEIGHTvar(varname) - Variable that holds the survey weight. The
weights are assumed to be equal if this option is omitted.

BARCOLOR1(string) - Valid Stata color used to represent respondents
with yvar == 1. This is the shade for the lower portion of the bars.
Default is pink.

BARCOLOR2(string) - Valid Stata color used to represent respondents
with yvar == 0 or missing. This is the shade for the upper portion of
the bars. Default is white.

LINECOLOR1(string) - Valid Stata color used to mark the boundaries
between the lower portions of the bars. (Should have good contrast
with BARCOLOR1.) Default is barcolor1*1.5.

LINECOLOR2(string) - Valid Stata color used to mark the boundaries
between the upper portions of the bars. (Should have good contrast with
BARCOLOR2.) Default is black*0.5.

EQUALWIDTH - If this option is included, all bars (clusters) that
have at least one non-missing value of yvar will appear with equal width,
regardless of the number of respondents in the cluster and regardless
of the values of the weightvar. (Note: EQUALWIDTH causes this program
to IGNORE the weightvar.)

SAVEDATA(string) - If this option is specified, the command will
save a dataset and name it using the string specified, which doesn't need
to be in double quotes. The dataset includes one row per bar in the plot.
The left-most bar is represented by row 1 and the right-most bar by the
last row in the dataset. The dataset holds several informative columns
describing what variable is summarized, how many respondents are
represented in each bar, the proportion of the population represented by
each bar, and the sample coverage in each bar (rounded to the nearest
percent). This dataset can be useful for identifying the cluster ID for
bars that show surprisingly low or surprisingly high coverage. SAVEDATA
uses the replace option when saving the dataset, so an existing dataset
with the same filename will be overwritten.

EXPORTSTRAtumname - If this option is specified, the command will
export a .PNG image of the plot to the current working directory and uses
the string from the stratum option as the filename. If user wants a
different filename or a different directory, use the export
option.

EXPORT(string) - Specify a filename and extension where the plot
should be exported (e.g., plot.png). Use an extension that is
compatible with the graph export width option (e.g., .png or .tif).

EXPORTwidth(integer) - The default width of opplot's export option
is 2000 pixels. You may specify a different width with this option.

TWOWAY(string) - The opplot command calls Stata's twoway command
for plotting. You may use the twoway option to pass through any valid
twoway options that are not already hard-coded here. See the list
below under 'All Else'.

PLOTN - If specified, the plot will include a second y-axis and a
line showing the number of respondents (N) per cluster. User may specify
the properties of the line and of the axis title and labels using options
listed below.

NLINEColor(string) - Color for the line that shows N.

NLINEWidth(string) - Width of the line that shows N.

NLINEPattern(string) - Pattern of the line that shows N.

YTITLE2(string) - Title for second y-axis if the user specifies the
PLOTN option. Default is "Number of Respondents".

YROUND2(integer 5) - Affects the labels on the second y-axis if the
user specifies the PLOTN option. The scale will run from 0 up to the
(maximum number of respondents in a cluster plus one) rounded up to the next multiple
of YROUND2. Default is to round up to the next multiple of 5.

FOOTNOTECOVG - Adds the Estimated Coverage as a footnote to the plot.

FOOTNOTEDEFF - Adds the Design Effect as a footnote to the plot.

FOOTNOTEICC - Adds the Intercluster Correlation Coefficient as a footnote to the plot.

All Else - Several standard twoway options are hard-coded as pass-thru
options here. These include title, subtitle, note, xtitle, ytitle, xlabel,
ylabel, saving, name, xsize and ysize. Note that ytitle defaults to "Percent of cluster".
You may specify ytitle(" ") to see a blank title or ytitle(none) will
yield no ytitle and will therefore shift the figure slightly to the left. Note that
with the name option, the user only needs to specify the name; the
code always includes the replace option when the user specifies a name.
Note also that the footnote option is a
synonym for the note option.) (See twoway_options).

Add High, Medium and Low Coverage Categories

The next set of input options should only be used to see the plot stratified into high, medium and low coverage categories.

LCTHRESHold(integer) - Low coverage threshold holds the numeric percent value used to identify low coverage.
All clusters with coverage less than or equal to this number will be assigned to the low category.
If not specified, all of the options listed below will be ignored.
If specified, you should use a note to tell the reader the meaning of the three bar colors. (At this time, opplot does not use a legend.)

HIGH(integer) - High coverage threshold holds the numeric percent value used to identify high coverage.
All clusters with coverage greater than or equal to this number will be assigned to the high cagtegory. Default value is 100.

(Note: If you specify the same high and low threshold, then the plot will be stratified into only two categories: high vs. low and clusters with coverage EXACTLY equal to the threshold will fall in the low category.)

Each category (HIGH, MID and LOW) can have different color options specified for the bars and lines.

BARCOLORHIGH1(string) - Valid Stata color used to represent respondents with yvar == 1 with high coverage as specified in high.
This is the shade for the lower portion of the bars. Default is dark blue with RGB values 103 169 207.

BARCOLORHIGH2(string) - Valid Stata color used to represent respondents with yvar == 0 or missing with high coverage as specified in high.
This is the shade for the upper portion of the bars. Default is gs15.

LINECOLORHIGH1(string) - Valid Stata color used to mark the boundaries between the lower portions of the bars with high coverage as specified in high.
(Should have good contrast with BARCOLORHIGH1.) Default is gs15.

LINECOLORHIGH2(string) - Valid Stata color used to mark the boundaries between the upper portions of the bars with high coverage as specified in high.
(Should have good contrast with BARCOLORHIGH2.) Default is black*0.5.

BARCOLORMID1(string) - Valid Stata color used to represent respondents with yvar == 1 with middle coverage.
This is the shade for the lower portion of the bars. Default is light blue with RGB values 0 0 128.

BARCOLORMID2(string) - Valid Stata color used to represent respondents with yvar == 0 or missing with middle coverage.
This is the shade for the upper portion of the bars. Default is gs15.

LINECOLORMID1(string) - Valid Stata color used to mark the boundaries between the lower portions of the bars with middle coverage.
(Should have good contrast with BARCOLORMID1.) Default is gs15.

LINECOLORMID2(string) - Valid Stata color used to mark the boundaries between the upper portions of the bars with middle coverage.
(Should have good contrast with BARCOLORMID2.) Default is black*0.5.

BARCOLORLOW1(string) - Valid Stata color used to represent respondents with yvar == 1 with low coverage as specified in lcthreshold.
This is the shade for the lower portion of the bars. Default is orange with RGB values 255 91 0.

BARCOLORLOW2(string) - Valid Stata color used to represent respondents with yvar == 0 or missing with low coverage as specified in lcthreshold.
This is the shade for the upper portion of the bars. Default is gs15.

LINECOLORLOW1(string) - Valid Stata color used to mark the boundaries between the lower portions of the bars with low coverage as specified in lcthreshold.
(Should have good contrast with BARCOLORLOW1.) Default is gs15.

LINECOLORLOW2(string) - Valid Stata color used to mark the boundaries between the upper portions of the bars with low coverage as specified in lcthreshold.
(Should have good contrast with BARCOLORLOW2.) Default is gs15.

A note on bar width

If the user does not specify a weightvar and does not specify the
equalwidth option, then the data are assumed to be self-weighted and
each cluster's bar width is proportional to the number of respondents
there. (This is the same as saying that the bar width is proportional
to the sum of weights in the cluster.)

If the user does specify a weightvar, then each bar width is
proportional to the sum of weights in the cluster.

If the user specifies the equalwidth option, then every bar will have
equal width, regardless of whether the user specified the weightvar. In
other words, the equalwidth option will override the weightvar
option.

A note on conflicting versions of opplot.ado

This program is currently available from two sources: 1) as a
standalone command from the Stata SSC, and 2) as part of a bundle
of programs called the Vaccination Coverage Quality Indicators (VCQI)
from the World Health Organization. The code is meant to be precisely
the same from both sources, but over time there is a danger that you
will have an old version from one source and an updated version from the
other. You will need to check your adopath to see which version is
used when you invoke the command.

Examples - See accompanying opplot_demo.do to run these examples

* Make fake data with 2 strata with 10 clusters each with 10 respondents each
. clear all
. set seed 8675309
. set obs 200
. gen clusterid = mod(_n-1,10)+1
. bysort clusterid: gen stratumid = _n <= 10

* The yes/no outcome variable here is y. It can take values of 0, 1, or missing(.).
* If it takes any other values, opplot will complain and abort.

. gen y = runiform() > clusterid/10
* Artificially boost coverage in stratum 1
. replace y = 1 if runiform() > .5 & stratumid == 1

* Basic demo...two plots...one for each stratum
. opplot y , clustvar(clusterid) stratvar(stratumid) stratum(0) title(Stratum 0) name(Demo0,replace)
. opplot y , clustvar(clusterid) stratvar(stratumid) stratum(1) title(Stratum 1) name(Demo1,replace)

* Without the stratum arguments, all data are plotted
opplot y , clustvar(clusterid) title(All Strata) name(Demo2, replace)

* Change bar colors
. opplot y , clustvar(clusterid) stratvar(stratumid) ///
stratum(1) title(Stratum 1) name(Demo3,replace) ///
barcolor1(red) barcolor2(gs8)

* Demo different bar widths if weights differ
. gen weight = 1
. replace weight = 2 if clusterid == 1
. save fauxdata, replace

. opplot y , clustvar(clusterid) stratvar(stratumid) ///
weightvar(weight) ///
stratum(1) title(Stratum 1) name(Demo4,replace) ///
barcolor1(red) barcolor2(gs8)

* Change line colors
. opplot y , clustvar(clusterid) stratvar(stratumid) ///
weightvar(weight) ///
stratum(1) title(Stratum 1) name(Demo5,replace) ///
barcolor1(red) barcolor2(gs8)	///
linecolor1(white) linecolor2(green)

* Change ylabel
* Demo ylabel xtitle ytitle subtitle footnote
* Demo export
. opplot y , clustvar(clusterid) stratvar(stratumid) ///
weightvar(weight) ///
stratum(1) title(Stratum 1) name(Demo6,replace) ///
ylabel(0(25)100,angle(0)) ///
xtitle(XTitle) ytitle(YTitle) ///
subtitle(Subtitle) footnote(Footnote) ///
export(Stratum_1.png)

* The exportstratumname option saves you the trouble of coming
* up with the export filename
. opplot y , clustvar(clusterid) stratvar(stratumid) ///
stratum(0) title(Stratum 0) name(Demo0,replace) ///
exportstratumname

* The exportwidth options lets you specify that a larger file is saved
* with better resolution for some purposes
. opplot y , clustvar(clusterid) stratvar(stratumid) ///
stratum(0) title(Stratum 0) name(Demo0,replace) ///
exportstratumname exportwidth(3000)

* Demo changing the aspect ratio of the figure using xsize and ysize
. opplot y , clustvar(clusterid) stratvar(stratumid) ///
stratum(0) title(Stratum 0) name(Demo7,replace) ///
xsize(20) ysize(6) export(Stratum_0_wide.png)

* Demo saving the accompanying dataset and having a look at it
. opplot y , clustvar(clusterid) stratvar(stratumid) ///
stratum(0) title(Stratum 0) name(Demo7,replace) ///
xsize(20) ysize(6) savedata(Demo7)
. use Demo7, clear
. browse

. use fauxdata, clear

* Demo plotting the number of respondents
. opplot y , clustvar(clusterid) stratvar(stratumid) ///
stratum(0) title(Stratum 0) name(Demo8,replace) ///
xsize(20) ysize(6) plotn

* Demo plotting the number of respondents using all related options
. opplot y , clustvar(clusterid) stratvar(stratumid) ///
stratum(0) title(Stratum 0) name(Demo9,replace) ///
xsize(20) ysize(6) plotn nlinecolor(red) nlinewidth(*2) ///
nlinepattern(dash) ytitle2(Number of Respondents (N)) ///
yround2(2)

* Demo adding high, medium and low coverage categories.
* Only specify the lcthreshold. All other values will use defaults.
. opplot y , clustvar(clusterid) stratvar(stratumid) ///
stratum(1) title(Stratum 1) name(Demo10,replace) ///
lcthreshold(50) ///
note("Different colors for clusters with a) 100% coverage, b) >50% and < 100%, and c) <= 50%.")

* Demo adding high, medium and low coverage categories.
* Specify both the lcthreshold (slightly lower than previous run) and high. All other values will use defaults.
. opplot y , clustvar(clusterid) stratvar(stratumid) ///
stratum(0) title(Stratum 0) name(Demo11,replace) ///
lcthreshold(20) high(90) ///
note("Different colors for clusters with a) >= 90% coverage, b) >20% and < 90%, and c) <= 20%.")

* Demo adding high, medium and low coverage categories with specified barcolor options.
* Change both the lcthreshold and high. Define barcolors for high, medium and low coverage categories.
. opplot y , clustvar(clusterid) stratvar(stratumid) ///
stratum(0) title(Stratum 0) name(Demo12,replace) ///
lcthreshold(35) high(80) ///
barcolorhigh1(67 162 202) barcolormid1(123 204 196) barcolorlow1(186 228 188) ///
note("Different colors for clusters with a) >= 80% coverage, b) >35% and < 80%, and c) <= 35%.")

* Demo portraying only two categories by setting lcthreshold == high.
* Note that in this case, any clusters exactly equal to the threshold are
* shown in the *lower* category color.
. opplot y , clustvar(clusterid) stratvar(stratumid) ///
stratum(0) title(Stratum 0) name(Demo13,replace) ///
lcthreshold(50) high(50) ///
note("Different colors for clusters with a) > 50% coverage and b) <= 50%.")

Authors

Dale Rhoda, Mary Prier, and Mary Kay Trimner, Biostat Global Consulting

Email Dale.Rhoda@biostatglobal.com

Links to YouTube Videos

The opplot command is distributed with (but not dependent upon) the
World Health Organization's suite of Stata programs known as the
Vaccination Coverage Quality Indicators (VCQI) (pronounced Vicki).
Organ pipe plots are described in some of the VCQI training videos:

Organ Pipe Plots - Overview

Organ Pipe Plots - Drilling Down
(Describes useful features of the optional dataset that can be saved with
each plot.)

Links to PowerPoint Presentations

Organ pipe plots were featured in a talk at the 2018 Stata Conference.

2018 conference presentation

Includes additional slides that describe new features