Installation | Syntax | Examples | Feedback | Change log
(07 May 2025)
This package provides the ability to draw tri-variate plots in Stata.
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.
The SSC version (v1.2):
ssc install ternary, replace
Or it can be installed from GitHub (v1.3):
net install ternary, from("https://raw.githubusercontent.com/asjadnaqvi/stata-ternary/main/installation/") replace
The palettes
package is required to run this command:
ssc install palettes, replace
ssc install colrspace, replace
Even if you have the package installed, make sure that it is updated 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:
ternary varL varR varB [if] [in], [ by(var) cuts(num) zoom pad(num) normalize(1|100) nofill points lines labels colorL(str) colorR(str)
colorB(str) lwidth(str) msymbol(str) msize(str) mcolor(str) mlcolor(str) mlwidth(str) labcolor(str) ticksize(str) mlabel(var)
mlabsize(str) mlabcolor(str) mlabposition(str) scale format(fmt) palette(str) legend(options) * ]
See the help file help ternary
for details.
The most basic use is as follows:
ternary varL varR varB
representing left, right and bottom variables respectively.
Software packages take countless hours of programming, testing, and bug fixing. If you use this package, then a citation would be highly appreciated.
The SSC citation is recommended. Please note that the GitHub version might be newer than the SSC version.
Users can either copy the files locally
foreach x in NUTS2_edu NUTS2_tourstay NUTS3_gva NUTS3_pop {
copy "https://github.com/asjadnaqvi/stata-ternary/raw/main/data/`x'.dta" "`x'.dta", replace
}
or load them directly from the server:
use "https://github.com/asjadnaqvi/stata-ternary/blob/main/data/NUTS3_pop.dta?raw=true", clear
Test a basic figure
ternary y15prop y64prop y99prop
Rearrange the variables and remove the fill
ternary y99prop y15prop y64prop, nofill
Test ternary
with fractions:
ternary y99prop y15prop y64prop, norm(1)
ternary y99prop y15prop y64prop
ternary y99prop y15prop y64prop, lcolor(black)
ternary y99prop y15prop y64prop, cuts(3)
ternary y99prop y15prop y64prop, cuts(10)
ternary y99prop y15prop y64prop, cuts(6)
ternary y99prop y15prop y64prop, cuts(6) zoom
ternary y99prop y15prop y64prop, cuts(6) zoom msize(2.5) mc(black%60) mlc(white)
ternary y99prop y15prop y64prop, cuts(8) zoom msize(2) mc(black%70) mlc(white) lw(0.08) labcolor(gs6)
ternary y99prop y15prop y64prop, cuts(8) zoom lw(0.08) labcolor(gs6) mlabel(NUTS_ID)
ternary y99prop y15prop y64prop, cuts(8) zoom lw(0.08) labcolor(gs6) ///
mlabel(NUTS_ID) mlabpos(12)
gen NUTS_ID2 = NUTS_ID if y99prop > 30
ternary y99prop y15prop y64prop, cuts(8) zoom lw(0.08) labcolor(gs6) ///
mlabel(NUTS_ID2) mlabpos(12)
ternary y99prop y15prop y64prop, zoom cuts(6) mcolor(white%60) ///
colorB(lime)
ternary y99prop y15prop y64prop, zoom cuts(6) ///
colorB(red) colorL(green) colorR(blue)
ternary y99prop y15prop y64prop, zoom cuts(4) ///
colorB(red) colorL(green) colorR(blue) mcolor(white%60) mlc(black) msize(3)
ternary y99prop y15prop y64prop, nofill points zoom cuts(6)
ternary y99prop y15prop y64prop, points zoom cuts(6) mlcolor(white)
ternary y99prop y15prop y64prop, nofill points zoom cuts(6) lw(0.05) msize(2.5) mlc(white)
ternary y99prop y15prop y64prop, nofill lines labels zoom cuts(6) msize(2.5) points malpha(80) mlc(white)
ternary y99prop y15prop y64prop, nofill lines labels zoom cuts(6) msize(1.5)
ternary y99prop y15prop y64prop, nofill lines labels zoom cuts(6) msize(1.5) mlc(black) mc(white%60)
ternary y99prop y15prop y64prop, nofill lines labels zoom cuts(6) msize(2) mlc(black) mc(white%80) lw(0.3) msym(triangle)
Plot the raw data and scale the markers to the total population:
ternary y_Y_GE65 y_Y15_64 y_Y_LT15, zoom lw(0.08) scale norm(100) mcolor(white%70) msize(0.8)
gen ctry=substr(NUTS_ID, 1, 2)
ternary y_Y_GE65 y_Y15_64 y_Y_LT15 if ctry=="DE", zoom lw(0.08) scale norm(100) mcolor(white%60) msize(0.8) pad(2)
Generate a region variable for EU countries:
*** taken from https://en.wikipedia.org/wiki/EuroVoc
gen region = .
replace region = 1 if inlist(ctry, "AT", "BE", "FR", "DE", "IE" , "LI", "LU", "MK")
replace region = 1 if inlist(ctry, "NL", "CH", "UK")
replace region = 2 if inlist(ctry, "DK", "IS", "EE", "FI", "LV", "LT", "SI", "NO")
replace region = 3 if inlist(ctry, "CY", "EL", "IT", "MT", "PT" , "ES", "TR")
replace region = 4 if inlist(ctry, "AL", "CZ", "HR", "HU", "PL", "RO", "RS")
replace region = 4 if inlist(ctry, "SE", "SK", "MK", "ME", "BG")
lab de region 4 "Central and Eastern Europe" 2 "Northern Europe" 3 "Southern Europe" 1 "Western Europe", replace
lab val region region
ternary y_Y_GE65 y_Y15_64 y_Y_LT15 , by(region) cuts(4) zoom lw(0.08) norm(100) mcolor(white%70) msize(1.8) pad(2)
ternary y_Y_GE65 y_Y15_64 y_Y_LT15 , by(region) cuts(4) nofill zoom lw(0.08) norm(100) mcolor(white%70) msize(1.2) pad(2)
ternary y_Y_GE65 y_Y15_64 y_Y_LT15 , by(region) cuts(2) zoom lw(0.08) norm(100) msymbol(triangle circle square diamond) msize(0.2) pad(2) nofill scale legend(size(2) pos(6) rows(2))
ternary y_Y_GE65 y_Y15_64 y_Y_LT15, by(region) cuts(2) nofill malpha(100) zoom lw(0.08) norm(100) msymbol(circle) msize(1) pad(2) palette(burd) mlcolor(white) mlwidth(0.06)
Please open an issue to report errors, feature enhancements, and/or other requests.
v1.3 (07 May 2025)
- Option
by()
added to allow markers to vary by categories. - Option
msymbol()
now accepts lists. If there are fewer markers defined than the by categories, then the last marker will be used for the remaining. - Option
palette()
added to customize marker colors. - Option
legend()
added to control howby()
legends are drawn. - Various bug fixes.
v1.2 (12 Mar 2025)
- Option
fill
is now the default and has been removed. Insteadnofill
has been added to remove the colors. This aligns the package to also how it was intended to be drawn by default. - Option
norm(100)
show now work properly. - Option
scale
has been added to scale the markers to the total of the raw data. In order to use this correctly, specify the raw data and selectnorm(100)
ornorm(1)
. - Option
zoom
should now result in tighter bounds. - Option
pad()
has been added to extended the zoom bounds. Default ispad(5)
fof 5%.
v1.1 (12 Sep 2024)
- Added
norm()
option which can be used to normalize the data to 1 (norm(1)
) or 100 (norm(100)
). - Added marker label options:
mlabel()
,mlabcolor()
,mlabposition()
,mlabsize()
. - Better zoom option.
- Minor code cleanups.
v1.0 (28 Aug 2024)
- First release.