Skip to content

Commit

Permalink
v1.7 fix #22 update #21
Browse files Browse the repository at this point in the history
  • Loading branch information
asjadnaqvi committed Nov 6, 2023
1 parent e424b77 commit 7a31e27
Show file tree
Hide file tree
Showing 45 changed files with 126 additions and 58 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.61
date-released: 2023-07-22
version: 1.7
date-released: 2023-11-06
url: "https://github.com/asjadnaqvi/stata-sankey"
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2022 Asjad Naqvi
Copyright (c) 2023 Asjad Naqvi

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
32 changes: 23 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@

---

# sankey v1.61
(22 Jul 2023)
# sankey v1.7
(06 Nov 2023)

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 @@ -25,7 +25,7 @@ SSC (**v1.6**):
ssc install sankey, replace
```

GitHub (**v1.61**):
GitHub (**v1.7**):

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

The syntax for **v1.6** is as follows:

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

See the help file `help sankey` for details.
Expand Down Expand Up @@ -204,7 +205,7 @@ sankey value, from(source) to(destination) by(layer) sort1(name, reverse) sort2(

Custom sorting on a value:

```
```stata
gen source2 = .
gen destination2 = .
Expand All @@ -217,7 +218,7 @@ foreach x in source destination {
replace `x'2 = 6 if `x'=="Medium"
replace `x'2 = 7 if `x'=="Website"
replace `x'2 = 8 if `x'=="Homepage"
replace `x'2 = 9 if `x'=="T```otal"
replace `x'2 = 9 if `x'=="Total"
replace `x'2 = 10 if `x'=="Google"
replace `x'2 = 11 if `x'=="Facebook"
}
Expand Down Expand Up @@ -338,6 +339,13 @@ sankey value, from(source) to(destination) by(layer) ctitles("Cat 1" "Cat 2" "Ca

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

```
sankey value, from(source) to(destination) by(layer) ctitles("Cat 1" "Cat 2" "Cat 3" "Cat 4" "Cat 5") ctpos(top) ctg(100) recenter(top)
```

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


### label rotation and offset

```
Expand Down Expand Up @@ -419,6 +427,12 @@ Please open an [issue](https://github.com/asjadnaqvi/stata-sankey/issues) to rep

## Change log

**v1.7 (06 Nov 2023)**
- Fixed `valcond()` dropping bar values.
- Fixed `ctitles()` getting random colors. It now defaults to black.
- Added `ctpos()` option to change column title position.
- Added `percent` option which is still beta. Convert flows to percent values.

**v1.61 (22 Jul 2023)**
- `saving()` option added (requested by Anirban Basu).
- Minor fixes.
Expand Down
Binary file modified figures/sankey10.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 modified figures/sankey2_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 modified figures/sankey2_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 modified figures/sankey3_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 modified figures/sankey3_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 modified figures/sankey4_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 modified figures/sankey4_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 modified figures/sankey5.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 modified figures/sankey5_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 modified figures/sankey5_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 modified figures/sankey5_2_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 modified 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 modified figures/sankey5_2_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 modified figures/sankey5_2_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 modified figures/sankey5_2_5.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_6.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 modified figures/sankey5_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 modified figures/sankey5_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 modified figures/sankey5_5.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 modified figures/sankey6.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 modified figures/sankey6_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 modified figures/sankey6_10.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 modified figures/sankey6_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 modified figures/sankey6_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 modified figures/sankey6_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 modified figures/sankey6_5.png
Binary file modified figures/sankey6_6.png
Binary file modified figures/sankey6_7.png
Binary file modified figures/sankey6_8.png
Binary file modified figures/sankey6_9.png
Binary file added figures/sankey6_9_1.png
Binary file modified figures/sankey7.png
Binary file modified figures/sankey8_1.png
Binary file modified figures/sankey8_2.png
Binary file modified figures/sankey8_3.png
Binary file modified figures/sankey8_4.png
Binary file modified figures/sankey9_1.png
Binary file modified figures/sankey9_2.png
86 changes: 67 additions & 19 deletions installation/sankey.ado
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
*! sankey v1.61 (22 Jul 2023)
*! sankey v1.7 (06 Nov 2023)
*! Asjad Naqvi (asjadnaqvi@gmail.com)

*v1.7 (06 Nov 2023): fix valcond() dropping labels in bars, added percent (still in beta), add ctitlepos() option. minor cleanups
*v1.61 (22 Jul 2023): Adding saving() option. minor fixes
*v1.6 (11 Jun 2023): Major rewrite of the core routines. Labels added. twp sorts added. Program is faster.
*v1.52 (29 May 2023): Add option where wwn flows are considered stock
Expand Down Expand Up @@ -28,13 +29,14 @@ 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) ] ///
[ LABAngle(string) LABSize(string) LABPOSition(string) LABGap(string) SHOWTOTal ] ///
[ VALSize(string) VALCONDition(real 0) format(string) VALGap(string) NOVALues ] ///
[ VALSize(string) VALCONDition(real 0) format(string) VALGap(string) NOVALues ] ///
[ LWidth(string) LColor(string) ] ///
[ offset(real 0) LABColor(string) ] /// // added v1.1
[ 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
[ BOXWidth(string) ] /// // added v1.3
[ wrap(real 7) CTITLEs(string asis) CTGap(real -10) CTSize(real 2.5) colorvar(varname) colorvarmiss(string) colorboxmiss(string) ] /// // v1.4 options
[ valprop labprop valscale(real 0.33333) labscale(real 0.3333) NOVALRight NOVALLeft NOLABels ] /// // v1.5
[ stock sort1(string) sort2(string) ] /// // v1.6
[ stock sort1(string) sort2(string) ] /// // v1.6
[ percent ctpos(string) ] /// // v1.7
[ title(passthru) subtitle(passthru) note(passthru) scheme(passthru) name(passthru) xsize(passthru) ysize(passthru) saving(passthru) ]


Expand Down Expand Up @@ -131,7 +133,7 @@ preserve

cap ren `by' xcut

egen layer = group(xcut)
egen layer = group(xcut)
replace layer = layer - 1

ren `from' var1
Expand All @@ -140,6 +142,24 @@ preserve

gen val2 = val1


if "`percent'" != "" { // suggestion by Mortiz Poll
tempvar aux1 aux2 total

bysort layer (var1 var2): egen double `total' = sum(val1)
replace val1 = (val1 / `total') * 100

bysort var1 layer clrlvl: egen double `aux1' = sum(val2)
replace `aux1' = 0 if clrlvl == 0
bysort layer: egen double `aux2' = sum(`aux1')
replace val2 = (val2 / `aux2') * 100

gsort layer val1 val2
}




gen id = _n


Expand Down Expand Up @@ -167,18 +187,18 @@ preserve

sort layer2 var marker

bysort layer2 var: egen val_out_temp = sum(val) if marker==1 // how much value is sent out
bysort layer2 var: egen val_in_temp = sum(val) if marker==2 & markme!=1 // how many value comes in
bysort layer2 var: egen double val_out_temp = sum(val) if marker==1 // how much value is sent out
bysort layer2 var: egen double val_in_temp = sum(val) if marker==2 & markme!=1 // how many value comes in

bysort layer2 var: egen val_out = max(val_out_temp)
bysort layer2 var: egen val_in = max(val_in_temp)
bysort layer2 var: egen double val_out = max(val_out_temp)
bysort layer2 var: egen double val_in = max(val_in_temp)

drop *temp

sort layer var marker
recode val_in val_out (.=0)

egen height = rowmax(val_in val_out) // this is the maximum height for each category for each group.
egen double height = rowmax(val_in val_out) // this is the maximum height for each category for each group.

// sort by name or value

Expand Down Expand Up @@ -499,11 +519,23 @@ preserve
if "`labgap'" == "" local labgap 0
if "`valsize'" == "" local valsize 1.5
if "`valgap'" == "" local valgap 2
if "`format'" == "" local format "%12.0f"
if "`boxwidth'" == "" local boxwidth 3.2
if "`colorboxmiss'" == "" local colorboxmiss gs10


if "`format'" == "" {
if "`percent'" != "" {
local format "%5.2f"

}
else {
local format "%12.0f"
}
}




format val `format'


Expand Down Expand Up @@ -640,19 +672,26 @@ preserve
summ labwgt if id==`x', meanonly
local labw = r(mean)

local boxlabel `boxlabel' (scatter ymid layer2 if tag_spike==1 & height >= `valcondition' & id==`x', msymbol(none) mlabel(lab2) mlabsize(`labw') mlabpos(`labposition') mlabgap(`labgap') mlabangle(`labangle') mlabcolor(`labcolor')) ///
local boxlabel `boxlabel' (scatter ymid layer2 if tag_spike==1 & id==`x', msymbol(none) mlabel(lab2) mlabsize(`labw') mlabpos(`labposition') mlabgap(`labgap') mlabangle(`labangle') mlabcolor(`labcolor')) ///

}

}
else {

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

}
}



local flowval val

if "`percent'" != "" {
gen valper = string(val, "`format'") + "%" if (marker==1 | marker==2)
local flowval valper
}


**** arc labels

Expand All @@ -668,12 +707,12 @@ preserve
if "`valprop'" == "" {

if "`novalleft'" == "" {
local values `values' (scatter arcmid layer2 if val >= `valcondition' & marker==1, msymbol(none) mlabel(val) mlabsize(`valsize') mlabpos(3) mlabgap(`valgap') mlabcolor(`labcolor')) ///
local values `values' (scatter arcmid layer2 if val >= `valcondition' & marker==1, msymbol(none) mlabel(`flowval') mlabsize(`valsize') mlabpos(3) mlabgap(`valgap') mlabcolor(`labcolor')) ///

}

if "`novalright'" == "" {
local values `values' (scatter arcmid layer2 if val >= `valcondition' & marker==2, msymbol(none) mlabel(val) mlabsize(`valsize') mlabpos(9) mlabgap(`valgap') mlabcolor(`labcolor')) ///
local values `values' (scatter arcmid layer2 if val >= `valcondition' & marker==2, msymbol(none) mlabel(`flowval') mlabsize(`valsize') mlabpos(9) mlabgap(`valgap') mlabcolor(`labcolor')) ///

}
}
Expand Down Expand Up @@ -704,12 +743,21 @@ preserve

if `"`ctitles'"' != "" {

if "`ctpos'" == "bot" | "`ctpos'" == "" {
local cty = -5 + `ctgap'
}

if "`ctpos'" == "top" {
summ y2, meanonly
local cty = `r(max)' + `ctgap'
}

local clabs `"`ctitles'"'
local len : word count `clabs'


gen title_x = .
gen title_y = `ctgap' in 1/`len'
gen title_y = `cty' in 1/`len'
gen title_name = ""


Expand All @@ -724,7 +772,7 @@ preserve
**** column labels

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

}

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.61
v 1.7
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: 20230525
d Distribution-Date: 20231106
d
d This version: 22 Jul 2023
d This version: 06 Nov 2023
d First version: 08 Dec 2022
d License: MIT
d
Expand Down
Loading

0 comments on commit 7a31e27

Please sign in to comment.