Skip to content

Commit

Permalink
v1.5 fix #14 #10
Browse files Browse the repository at this point in the history
  • Loading branch information
asjadnaqvi committed Apr 30, 2023
1 parent fc7731b commit 56955de
Show file tree
Hide file tree
Showing 14 changed files with 234 additions and 41 deletions.
4 changes: 2 additions & 2 deletions CITATION.cff
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@ authors:
- family-names: "Naqvi"
given-names: "Asjad"
title: "Stata package ``sankey''"
version: 1.31
date-released: 2023-04-04
version: 1.5
date-released: 2023-04-30
url: "https://github.com/asjadnaqvi/stata-sankey"
72 changes: 66 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

---

# sankey v1.4
# sankey v1.5

This package allows users to draw Sankey plots in Stata. It is based on the [Sankey Guide](https://medium.com/the-stata-guide/stata-graphs-sankey-diagram-ecddd112aca1) published on [the Stata Guide](https://medium.com/the-stata-guide) on Medium on October 2021.

Expand All @@ -21,7 +21,7 @@ SSC (**v1.31**):
ssc install sankey, replace
```

GitHub (**v1.4**):
GitHub (**v1.5**):

```
net install sankey, from("https://raw.githubusercontent.com/asjadnaqvi/stata-sankey/main/installation/") replace
Expand Down Expand Up @@ -56,17 +56,18 @@ graph set window fontface "Arial Narrow"

## Syntax

The syntax for **v1.4** is as follows:
The syntax for **v1.5** is as follows:

```applescript
sankey value [if] [in], from(var) to(var) by(var)
[ palette(str) colorby(layer|level) colorvar(var) colorvarmiss(str) colorboxmiss(str)
smooth(1-8) gap(num) recenter(mid|bot|top) ctitles(list) ctgap(num) ctsize(num)
labangle(str) labsize(str) labposition(str) labgap(str) showtotal
valsize(str) valcondition(num) format(str) valgap(str) novalues
lwidth(str) lcolor(str) alpha(num) offset(num) sortby(value|name) boxwidth(str)
labprop titleprop labscale(num) novalright novalleft nolabels
lwidth(str) lcolor(str) alpha(num) offset(num) sortby(value|name [, reverse]) boxwidth(str)
title(str) subtitle(str) note(str) scheme(str) name(str) xsize(num) ysize(num) ]
```

See the help file `help sankey` for details.
Expand Down Expand Up @@ -161,12 +162,24 @@ sankey value, from(source) to(destination) by(layer) sortby(name)

<img src="/figures/sankey5_1.png" height="600">

```
sankey value, from(source) to(destination) by(layer) sortby(name, reverse)
```

<img src="/figures/sankey5_1_1.png" height="600">

```
sankey value, from(source) to(destination) by(layer) sortby(value)
```

<img src="/figures/sankey5_2.png" height="600">

```
sankey value, from(source) to(destination) by(layer) sortby(value, reverse)
```

<img src="/figures/sankey5_2_1.png" height="600">

### boxwidth

```
Expand Down Expand Up @@ -248,7 +261,7 @@ palette(blue*0.1 blue*0.3 blue*0.5 blue*0.7) colorvarmiss(gs13) colorboxmiss(gs1

<img src="/figures/sankey6_6.png" height="600">

### column titles
### column titles (v1.4)

```
sankey value, from(source) to(destination) by(layer) ctitles(Cat1 Cat2 Cat3 Cat4 Cat5)
Expand All @@ -269,6 +282,47 @@ sankey value, from(source) to(destination) by(layer) ctitles("Cat 1" "Cat 2" "Ca
<img src="/figures/sankey6_9.png" height="600">


### hide values and labels (v1.5)

```
sankey value, from(source) to(destination) by(layer) novalleft
```

<img src="/figures/sankey8_1.png" height="600">

```
sankey value, from(source) to(destination) by(layer) novalright
```

<img src="/figures/sankey8_2.png" height="600">

```
sankey value, from(source) to(destination) by(layer) noval
```

<img src="/figures/sankey8_3.png" height="600">

```
sankey value, from(source) to(destination) by(layer) nolabels
```

<img src="/figures/sankey8_4.png" height="600">


### proportional values and labels (v1.5)


```
sankey value, from(source) to(destination) by(layer) valprop vals(2)
```

<img src="/figures/sankey9_1.png" height="600">

```
sankey value, from(source) to(destination) by(layer) labprop labs(2)
```

<img src="/figures/sankey9_2.png" height="600">

### All together

Expand All @@ -289,6 +343,12 @@ Please open an [issue](https://github.com/asjadnaqvi/stata-sankey/issues) to rep

## Change log

**v1.5 (30 Apr 2023)**
- Added `laprop`, `titleprop`, and `labscale()` for scaling values and labels.
- Added `novalright`, `novalleft`, `nolabels` options.
- Added `sortby(., reverse)` option.
- Help file improved in its layout.

**v1.4 (23 Apr 2023)**
- Fixed major bugs with unbalanced panels.
- Added column title options.
Expand Down
Binary file added figures/sankey5_1_1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added figures/sankey5_2_2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added figures/sankey8_1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added figures/sankey8_2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added figures/sankey8_3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added figures/sankey8_4.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added figures/sankey9_1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added figures/sankey9_2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
140 changes: 123 additions & 17 deletions installation/sankey.ado
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
*! sankey v1.4 (23 Apr 2023)
*! sankey v1.5 (30 Apr 2023)
*! Asjad Naqvi ([email protected])

*v1.5 (30 Apr 2023): add labprop, titleprop, labscale, novalright novalleft, sortby(, reverse) options, nolab
*v1.4 (23 Apr 2023): fix unbalanced. fixed gaps. Added column labels. Add custom color option.
*v1.31 (04 Apr 2023): fix to how colors are defined.
*v1.3 (26 Feb 2023): sortby() option added. Node bundling.
Expand All @@ -21,13 +22,14 @@ program sankey, sortpreserve
version 15

syntax varlist(numeric max=1) [if] [in], From(varname) To(varname) by(varname) ///
[ palette(string) smooth(numlist >=1 <=8) gap(real 5) RECENter(string) colorby(string) alpha(real 75) ] ///
[ palette(string) smooth(numlist >=1 <=8) gap(real 5) RECENter(string) colorby(string) alpha(real 75) ] ///
[ LABAngle(string) LABSize(string) LABPOSition(string) LABGap(string) SHOWTOTal ] ///
[ VALSize(string) VALCONDition(real 0) format(string) VALGap(string) NOVALues ] ///
[ LWidth(string) LColor(string) ] ///
[ offset(real 0) LABColor(string) ] /// // added v1.1
[ sortby(string) BOXWidth(string) ] /// // added v1.3
[ wrap(real 7) CTITLEs(string asis) CTGap(real -5) CTSize(real 2.5) colorvar(varname) colorvarmiss(string) colorboxmiss(string) ] /// // v1.4 options
[ valprop labprop labscale(real 0.3333) NOVALRight NOVALLeft NOLABels ] /// // v1.5
[ title(passthru) subtitle(passthru) note(passthru) scheme(passthru) name(passthru) xsize(passthru) ysize(passthru) ]


Expand All @@ -48,6 +50,11 @@ version 15
exit 198
}

if "`novalleft'" != "" & "`novalright'" != "" {
di as err "Both {it:novalleft} and {it:novalright} are not allowed. If you want to hide values use the {it:novalues} option instead."
exit 198
}

if "`colorvar'" != "" {
tempvar _temp
qui gen `_temp' = mod(`colorvar',1)
Expand Down Expand Up @@ -155,11 +162,40 @@ preserve
gen name`x' = lab2 if x2==`x'
replace name`x' = lab1 if x2==`y'

if "`sortby'" == "" | "`sortby'" == "value" {



if "`sortby'" == "" {
sort name`x' sort`x' val2 // numerical
}
if "`sortby'" == "name" {
sort name`x' sort`x' lab2 // alphabetical
else {
tokenize "`sortby'", p(",")
local stype `1'
local srev `3'


if ("`srev'" != "" & "`srev'" != "reverse") {
di as error "Valid options are sortby(name, reverse) or sortby(value, reverse)."
exit
}

if "`stype'" == "value" {
if "`srev'" != "reverse" {
sort name`x' sort`x' val2 // numerical
}
else {
gsort name`x' sort`x' -val2 // numerical reverse
}
}

if "`stype'" == "name" {
if "`srev'" != "reverse" {
sort name`x' sort`x' lab2 // alphabetical
}
else {
gsort name`x' sort`x' -lab2 // alphabetical reverse
}
}
}

by name`x': replace sort`x' = sort`x'[1]
Expand Down Expand Up @@ -194,7 +230,6 @@ preserve
order id



egen grp1 = group(x1 order1) // out grp by layer
egen grp2 = group(x1 order2) // in grp by layer

Expand Down Expand Up @@ -289,8 +324,6 @@ preserve
}




//// add gaps

sort layer id x
Expand Down Expand Up @@ -760,6 +793,9 @@ preserve
}





**** PLOT EVERYTHING ***

if "`labangle'" == "" local labangle 90
Expand All @@ -771,28 +807,98 @@ preserve
if "`format'" == "" local format "%12.0f"
format val `format'



summ ymax, meanonly
local yrange = r(max)

if "`showtotal'" != "" {
gen lab2 = lab + " (" + string(sums, "`format'") + ")" if tag==1
}
else {
gen lab2 = lab if tag==1
}



*local wrap2 = `wrap' + 2
*replace lab2 = substr(lab2, 1, `wrap') + "`=char(10)`=char(39)'" + substr(lab2, `wrap2', .) if tag==1

**** arc labels

if "`valprop'" != "" {
summ val if tag==1, meanonly
gen labwgt = `valsize' * (val / r(max))^`labscale' if midp!=.
}
else {
gen labwgt = 1 if midp!=.
}

if "`novalues'" == "" {
local values `values' (scatter midp x if val >= `valcondition', msymbol(none) mlabel(val) mlabsize(`valsize') mlabpos(3) mlabgap(`valgap') mlabcolor(`labcolor')) ///
if "`valprop'" == "" {

if "`novalleft'" == "" {
local values `values' (scatter midp x if val >= `valcondition', msymbol(none) mlabel(val) mlabsize(`valsize') mlabpos(3) mlabgap(`valgap') mlabcolor(`labcolor')) ///

}

if "`novalright'" == "" {
local values `values' (scatter midpin xin if val >= `valcondition', msymbol(none) mlabel(val) mlabsize(`valsize') mlabpos(9) mlabgap(`valgap') mlabcolor(`labcolor')) ///

}
}
else {

levelsof id, local(lvls)

foreach x of local lvls {
summ labwgt if id==`x', meanonly
local labsz = r(mean)

if "`novalleft'" == "" {
local values `values' (scatter midp x if val >= `valcondition' & id==`x', msymbol(none) mlabel(val) mlabsize(`labsz') mlabpos(3) mlabgap(`valgap') mlabcolor(`labcolor')) ///

}

if "`novalright'" == "" {
local values `values' (scatter midpin xin if val >= `valcondition' & id==`x', msymbol(none) mlabel(val) mlabsize(`labsz') mlabpos(9) mlabgap(`valgap') mlabcolor(`labcolor')) ///

}
}

}
}


**** box labels

if "`nolabels'" == "" {
if "`showtotal'" != "" {
gen lab2 = lab + " (" + string(sums, "`format'") + ")" if tag==1
}
else {
gen lab2 = lab if tag==1
}

local values `values' (scatter midpin xin if val >= `valcondition', msymbol(none) mlabel(val) mlabsize(`valsize') mlabpos(9) mlabgap(`valgap') mlabcolor(`labcolor')) ///

if "`labprop'" != "" {
summ sums if tag==1, meanonly
gen titlewgt = `valsize' * (sums / r(max))^`labscale' if tag==1

levelsof id, local(lvls)

foreach x of local lvls {
summ titlewgt if id==`x', meanonly
local titlez = r(mean)

local boxlabel `boxlabel' (scatter midy x if tag==1 & val >= `valcondition' & id==`x', msymbol(none) mlabel(lab2) mlabsize(`titlez') mlabpos(`labposition') mlabgap(`labgap') mlabangle(`labangle') mlabcolor(`labcolor')) ///

}

}
else {

local boxlabel (scatter midy x if tag==1 & val >= `valcondition', msymbol(none) mlabel(lab2) mlabsize(`labsize') mlabpos(`labposition') mlabgap(`labgap') mlabangle(`labangle') mlabcolor(`labcolor')) ///

}
}

**** column labels

if `"`ctitles'"' != "" {
local lvllab (scatter title_y title_x, msymbol(none) mlabel(title_name) mlabpos(0) mlabsize(`ctsize')) ///

Expand All @@ -810,7 +916,7 @@ preserve
twoway ///
`shapes' ///
`boxes' ///
(scatter midy x if tag==1 & val >= `valcondition', msymbol(none) mlabel(lab2) mlabsize(`labsize') mlabpos(`labposition') mlabgap(`labgap') mlabangle(`labangle') mlabcolor(`labcolor')) ///
`boxlabel' ///
`values' ///
`lvllab' ///
, ///
Expand Down
6 changes: 3 additions & 3 deletions installation/sankey.pkg
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
v 1.4
v 1.5
d {bf:SANKEY}: A Stata package for sankey plots.
d See {bf:help sankey} after installation.
d
Expand All @@ -8,9 +8,9 @@ d KW: Stata
d KW: graphs
d KW: sankey
d
d Distribution-Date: 20230423
d Distribution-Date: 20230430
d
d This version: 23 Apr 2023
d This version: 30 Apr 2023
d First version: 08 Dec 2022
d License: MIT
d
Expand Down
Loading

0 comments on commit 56955de

Please sign in to comment.