Installation | Syntax | Examples | Feedback | Change log
(23 Sep 2025)
The package can be installed via SSC or GitHub. The GitHub version, might be more recent due to bug fixes, feature updates etc, and may contain syntax improvements and changes in default values. See version numbers below. Eventually the GitHub version is published on SSC.
SSC (v1.5):
ssc install alluvial, replace
GitHub (v1.51):
net install alluvial, from("https://raw.githubusercontent.com/asjadnaqvi/stata-alluvial/main/installation/") replace
The palettes package is required to run this command:
ssc install palettes, replace
ssc install colrspace, replace
Even if you have these packages installed, please check for updates: ado update, update.
If you want to make a clean figure, then it is advisable to load a clean scheme. These are several available and I personally use the following:
ssc install schemepack, replace
set scheme white_tableau
You can also push the scheme directly into the graph using the scheme(schemename) option. See the help file for details or the example below.
I also prefer narrow fonts in figures with long labels. You can change this as follows:
graph set window fontface "Arial Narrow"The syntax for the latest version is as follows:
alluvial varlist [if] [in] [weight],
[ value(var) palette(str) colorby(layer|level) smooth(1-8) gap(num) recenter(mid|bot|top) shares percent
labangle(str) labsize(str) labposition(str) labcolor(str) labgap(str)
catangle(str) catsize(str) catposition(str) catcolor(str) catgap(str)
valsize(str) valcondition(num) format(str) valgap(str) novalues showtotal novalleft novalright
lwidth(str) lcolor(str) alpha(num) offset(num) boxwidth(str)
wraplabel(num) wrapcat(num) valprop labprop valscale(num) labscale(num) n(num) * ]See the help file help alluvial for details.
The most basic use is as follows:
alluvial varlist
where varlist are categorival variables given at the unit of observation. If any variable has more than 10 categories, or it is continuous, the command will throw an error. This is to avoid over-crowding the figure. For suggestions on how to automate this, please open an issue!
Load a Stata dataset:
sysuse nlsw88.dta, clearLet's test the alluvial command:
alluvial race married collgrad smsa unionalluvial race married collgrad smsa union, smooth(1)alluvial race married collgrad smsa union, smooth(8)alluvial race married collgrad smsa union, colorby(layer)alluvial race married collgrad smsa union, palette(carto)alluvial race married collgrad smsa union, palette(CET I2)alluvial race married collgrad smsa union, sharesalluvial race married collgrad smsa union, showmiss sharesalluvial race married collgrad smsa union, showmiss shares colorby(layer)alluvial race married collgrad smsa union, gap(0)alluvial race married collgrad smsa union, gap(10)local vars race married collgrad smsa union
alluvial `vars', smooth(8) alpha(60) palette(CET C7) gap(10) valcond(100) valsize(2) showtot ///
xsize(2) ysize(1) lc(black) lw(0.1) local vars race married collgrad smsa union
alluvial `vars', smooth(8) alpha(60) palette(CET C7) gap(10) valcond(100) valsize(2) showtot ///
xsize(2) ysize(1) lc(black) lw(0.1) ///
laba(0) labpos(3) noval offset(6)local vars race married collgrad smsa union
alluvial `vars', smooth(8) alpha(60) palette(CET C7) gap(10) valcond(100) valsize(2) showtot ///
xsize(2) ysize(1) lc(black) lw(0.1) ///
laba(0) labpos(3) noval offset(6) boxwid(6)alluvial race married collgrad smsa union, smooth(8) alpha(60) palette(CET C6) valsize(2) ///
lw(0.1) lc(black) ///
laba(0) gap(2) novalright showtotal ///
xsize(2) ysize(1) alluvial race married collgrad smsa union, smooth(8) alpha(60) palette(CET C6) valsize(2) ///
lw(0.1) lc(black) ///
laba(0) labs(1.6) boxw(10) gap(2) novalues ///
showtotal wrapcat(20) wraplab(15) catgap(8) plotregion(margin(b+5 l+10 r+10)) ///
xsize(2) ysize(1) alluvial race married collgrad smsa union, smooth(8) alpha(60) palette(CET C6) valsize(2) ///
laba(0) labs(1.6) boxw(11) gap(2) novalues ///
showtotal wraplab(15) catgap(8) plotregion(margin(b+5 l+10 r+10)) ///
xsize(2) ysize(1) labprop showmissWhile percent converts the values to percentages proportional to column heights percent2 shows a pure columnwise share.
alluvial race married collgrad smsa union, smooth(8) alpha(60) palette(CET C6) valsize(2) ///
laba(0) labs(1.6) boxw(11) gap(2) novalues ///
showtotal wraplab(15) catgap(8) plotregion(margin(b+5 l+10 r+10)) ///
xsize(2) ysize(1) labprop percentalluvial race married collgrad smsa union, smooth(8) alpha(60) palette(CET C6) valsize(2) ///
laba(0) labs(1.6) boxw(11) gap(2) novalues ///
showtotal wraplab(15) catgap(8) plotregion(margin(b+5 l+10 r+10)) ///
xsize(2) ysize(1) labprop percent2alluvial race married collgrad smsa union, smooth(8) alpha(60) palette(CET C6) valsize(2) ///
laba(0) labs(1.6) boxw(11) gap(2) novalues ///
showtotal wrapcat(20) wraplab(15) catgap(8) plotregion(margin(b+5 l+10 r+10)) ///
xsize(2) ysize(1) labprop showmiss percent alluvial race married collgrad smsa union [w = wage], smooth(8) alpha(60) palette(CET C6) valsize(2) ///
laba(0) labs(1.6) boxw(11) gap(2) novalues ///
showtotal wrapcat(20) wraplab(15) catgap(8) plotregion(margin(b+5 l+10 r+10)) ///
xsize(2) ysize(1) showmiss labprop percent alluvial race married collgrad smsa union, value(wage) smooth(8) alpha(60) palette(CET C6) valsize(2) ///
laba(0) labs(1.6) boxw(11) gap(2) novalues ///
showtotal wrapcat(20) wraplab(15) catgap(8) plotregion(margin(b+5 l+10 r+10)) ///
xsize(2) ysize(1) showmiss labprop percent Please open an issue to report errors, feature enhancements, and/or other requests.
v1.51 (23 Sep 2025)
- Added option
dropmissthat drops any incomplete row. Might be useful ifshareorpercentoptions are being used. (requested by Emma Romell). - Minor code improvements.
v1.5 (27 Apr 2025)
- Complete rework of the base code. This command should now run much faster.
- Added option
percent2. This shows percentages based on column totals. catgapis now a percentage of column height to make it consistent across actual values and percentages.- Several bug fixes.
v1.42 (06 Mar 2025)
- The program was dropping missing values. This has been fixed.
v1.41 (11 Nov 2024)
- Added
value()to allow users to specify a numeric variable that can be aggregated over the categories. - Fixed a bug where string variable checks were not working properly.
- Minor improvements to the code.
v1.4 (26 Sep 2024)
- Added
wraplabel()andwrapcat()options that allow users to wrap long labels after specific characters. - Added
valpropandlabpropto scale labels proportional to their values. The scaling can be adjusted usinglabscale()andvalscale()options. - Added
novalleftandnovalrightto hide left (outgoing) and right (incoming) labels respectively. - Added
percentwhich now shows percentages based on column (layer) height. Note thatsharesis still available but will scale to [0,1] range. - Added option
n()to control how many points are used for calculating the sigmoid curves. - All generic
twoway graphoptions can now be passed ontoalluvialsuch asplotregion(),graphregion()and many others for more control. - Improvements to how weights are used in the command.
- Major code cleanup resulting in major speed improvements.
v1.3 (10 Feb 2024)
- Options added to control category variables including size, color, gap, angle, position.
- Option
labcolor()added. - Options
graphregion()andplotregion()added. - Minor code cleanups.
v1.21 (19 Oct 2023)
showmisswas not generating the missing values category (reported by Matthias Schonlau). This has been fixed.
v1.2 (04 Apr 2023)
if/inadded back in the command.boxwidth()added to the command.- Minor bug fixes.
v1.1 (15 Jan 2023)
- Variable labels are now correctly passing to the final graph (requested by Marc Kaulisch and Ana Karen Díaz Méndez).
- Weights option added. Still in beta so more testing is required (requested by Ana Karen Díaz Méndez).
offsetoption added to extend the x-axis (requested by Marc Kaulisch).valcondis now just a numeric. It is assumed that the condition implies>= <valcond>.- The missing category, enabled using the
showmissoption, now has its own color (requested by Marc Kaulisch).
v1.0 (08 Dec 2022)
- Public release.






















