Skip to content

Commit

Permalink
v1.2 update
Browse files Browse the repository at this point in the history
  • Loading branch information
asjadnaqvi committed Sep 23, 2022
1 parent b1c8863 commit f47aa46
Show file tree
Hide file tree
Showing 11 changed files with 123 additions and 77 deletions.
29 changes: 21 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
![StataMin](https://img.shields.io/badge/stata-2015-blue) ![issues](https://img.shields.io/github/issues/asjadnaqvi/stata-treemap) ![license](https://img.shields.io/github/license/asjadnaqvi/stata-treemap) ![Stars](https://img.shields.io/github/stars/asjadnaqvi/stata-treemap) ![version](https://img.shields.io/github/v/release/asjadnaqvi/stata-treemap) ![release](https://img.shields.io/github/release-date/asjadnaqvi/stata-treemap)


# treemap v1.1
# treemap v1.2


This package provides the ability to draw treemaps Stata.
Expand All @@ -13,13 +13,13 @@ It is based on D3's [treemap](https://observablehq.com/@d3/treemap) and Python's

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.0**):
The SSC version (**v1.1**):

```
ssc intall treemap, replace
```

Or it can be installed from GitHub (**v1.1**):
Or it can be installed from GitHub (**v1.2**):

```
net install treemap, from("https://raw.githubusercontent.com/asjadnaqvi/stata-treemap/main/installation/") replace
Expand Down Expand Up @@ -57,7 +57,7 @@ The syntax for v1.0 is as follows:

```
treemap numvar [if] [in], by(variables (min=1, max=3))
[ xsize(num) ysize(num) format(str) labcond(num) pad(list)
[ xsize(num) ysize(num) format(str) labcond(num) pad(list) fi(list)
labsize(list) linewidth(list) linecolor(list)
addtitles novalues nolabels labsize(num) titlegap(num)
labprop titleprop colorprop labscale(num) title(str) subtitle(str)
Expand All @@ -73,7 +73,7 @@ treemap numvar, by(variable(s))
```


where `numvar` is a numeric variable, and `by()` is upto three string variables, ordered by finer to higher aggregation units. The algorithm changes the layout based on the `width()` and `height()` defintions. See examples below.
where `numvar` is a numeric variable, and `by()` is upto three string variables, ordered by finer to higher aggregation units. The algorithm changes the layout based on `xsize()` and `ysize()`. See examples below.



Expand Down Expand Up @@ -256,21 +256,34 @@ treemap y_TOT, by(NUTS2 NUTS1 NUTS0) linew(none 0.1 none) linec(white black whit

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

### v1.2 updates

```
treemap y_TOT if NUTS0=="DE", by(NUTS3 NUTS2 NUTS1) linew(none 0.1 none) linec(white black white) labsize(1.4 1.8 2.4) format(%15.0fc) title("Population of Germany") pad(0.015 0.015 0.01) labprop titleprop palette(CET C6) addtitle noval fi(100 50 20)
```

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

## Feedback

Please open an [issue](https://github.com/asjadnaqvi/stata-treemap/issues) to report errors, feature enhancements, and/or other requests.


## Versions

**v1.1 (13 September 2022)**
**v1.2 (25 Sep 2022)**
- Fill intensity control added.
- Error checks for negative values.
- Minor code cleanups.

**v1.1 (13 Sep 2022)**
- Major update to the package
- Scaling options added for labels, titles, and colors
- Better checking for thresholds in how boxes are drawn
- Several bug fixes and clean ups to the code.

**v1.0 (08 September 2022)**
- First release
**v1.0 (08 Sep 2022)**
- First release.



Expand Down
Binary file modified figures/treemap17.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/treemap21.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/treemap22.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/treemap23.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/treemap24.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/treemap25.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions installation/stata.toc
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
v 1.1
v 1.2
d 'TREEMAP': A Stata package for treemaps
d
d Distribution-Date: 20220913
d Distribution-Date: 20220925
d
d Asjad Naqvi,
d asjadnaqvi@gmail.com
Expand Down
141 changes: 86 additions & 55 deletions installation/treemap.ado
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
*! Treemap v1.1 (13 Sep 2022)
*! Treemap v1.2 (22 Sep 2022)
*! Asjad Naqvi (asjadnaqvi@gmail.com)

* v1.2 (22 Sep 2022): Negative values check. Control over fill intensity.
* v1.1 (13 Sep 2022): Label, color, title scaling. More options for controls. More checks. Better defaults.
* v1.0 (08 Sep 2022): First release

Expand All @@ -13,7 +14,8 @@ prog def treemap, sortpreserve
syntax varlist(numeric max=1) [if] [in], by(varlist min=1 max=3) ///
[ XSize(real 5) YSize(real 3) format(str) palette(string) ADDTitles NOVALues NOLABels cond(string) ] ///
[ title(passthru) subtitle(passthru) note(passthru) scheme(passthru) name(passthru) ] ///
[ pad(numlist max=3) labprop labscale(real 0.333) labcond(real 0) colorprop titlegap(real 0.1) titleprop LINEWidth(string) LINEColor(string) LABSize(string) ] // v1.1 options. labscale is undocumented labprop scaling
[ pad(numlist max=3) labprop labscale(real 0.3333) labcond(real 0) colorprop titlegap(real 0.1) titleprop LINEWidth(string) LINEColor(string) LABSize(string) ] /// // v1.1 options. labscale is undocumented labprop scaling
[ fi(numlist max=3) ] // v1.2 options.

marksample touse, strok

Expand All @@ -23,6 +25,13 @@ prog def treemap, sortpreserve
qui ssc install carryforward, replace
}

qui summ `varlist' if `touse', meanonly
if r(min) < 0 {
di as error "`varlist' contains negative values. Either drop them or make them positive and generate a variable that marks positive and negative values."
exit
}



qui {
preserve
Expand Down Expand Up @@ -228,7 +237,45 @@ qui {
local ls2 1.6
}

mata: xmin = 0; xmax = `xsize'; ymin = 0; ymax = `ysize'; dy = ymax - ymin; dx = xmax - xmin

if "`fi'" != "" {
tokenize `fi'
local filen : word count `fi'

local fi2 `1'
local fi1 `1'
local fi0 `1'

if `filen' > 1 {
local fi1 `2'
local fi0 `2'
}

if `filen' > 2 {
local fi1 `2'
local fi0 `3'
}
}
else {
local fi0 100

if `length' == 2 {
local fi1 = 90
local fi0 = 60
}

if `length' == 3 {
local fi2 = 100
local fi1 = 75
local fi0 = 50
}
}


local ratio = (1 + sqrt(5)) / 2


mata: xmin = 0; xmax = `xsize'; ymin = 0; ymax = `ysize'; dy = ymax - ymin; dx = xmax - xmin; myratio = `ratio'


**************
Expand All @@ -239,7 +286,7 @@ qui {
mata: data = select(st_data(., ("var0_v")), st_data(., "var0_t=1"))
mata: padb = `pad0'; padt = `pad0'; padl = `pad0'; padr = `pad0'

mata: normlist = normdata(data, dx, dy); b0 = squarify(normlist, xmin, ymin, dx, dy), normlist; c0 = getcoords2(data, b0, padb, padt, padl, padr)
mata: normlist = normdata(data, dx, dy); b0 = squarify(normlist, xmin, ymin, dx, dy, myratio), normlist; c0 = getcoords2(data, b0, padb, padt, padl, padr)
mata: st_matrix("c0", c0)

local varlist
Expand Down Expand Up @@ -284,7 +331,7 @@ qui {
mata: mydata = select(mydata, mydata[.,2] :== `z')
mata: padb = `pad1'; padt = `pad1'; padl = `pad1'; padr = `pad1'

mata: b1_`z' = processchildren(`z', mydata[.,1], b0 , padb, padt, padl, padr)
mata: b1_`z' = processchildren(`z', mydata[.,1], b0 , padb, padt, padl, padr, myratio)
mata: c1_`z' = getcoords2( mydata[.,1], b1_`z', padb, padt, padl, padr)
mata: st_matrix("c1_`z'", c1_`z')

Expand Down Expand Up @@ -333,7 +380,7 @@ qui {
mata: mydata = select(st_data(., ("var2_v", "var0_o", "var1_o")), st_data(., "var2_t = 1"))
mata: mydata = select(mydata, mydata[.,2] :== `z' :& mydata[.,3] :== `y')
mata: padb = `pad2'; padt = `pad2'; padl = `pad2'; padr = `pad2'
mata: b2_`z'_`y' = processchildren(`y', mydata[.,1], b1_`z', padb, padt, padl, padr)
mata: b2_`z'_`y' = processchildren(`y', mydata[.,1], b1_`z', padb, padt, padl, padr, myratio)
mata: c2_`z'_`y' = getcoords2(mydata[.,1], b2_`z'_`y', padb, padt, padl, padr)
mata: st_matrix("c2_`z'_`y'", c2_`z'_`y')

Expand Down Expand Up @@ -373,19 +420,6 @@ qui {
local poptions `3'
}

local fi0 = 100

if `length' == 2 {
local fi0 = 60
local fi1 = 90
}

if `length' == 3 {
local fi0 = 50
local fi1 = 75
local fi2 = 100
}


***************
*** layer 0 ***
Expand Down Expand Up @@ -501,7 +535,6 @@ qui {
}



if `length' == 3 {
local mylab `lab2'
if "`addtitles'" != "" local boxlab `lab1_box' || `lab0_box'
Expand Down Expand Up @@ -530,7 +563,7 @@ qui {
xscale(off) yscale(off) ///
xlabel(, nogrid) ylabel(, nogrid) ///
xsize(`xsize') ysize(`ysize') ///
`title' `subtitle' `note' `scheme'
`title' `subtitle' `note' `scheme' `name'

restore
}
Expand Down Expand Up @@ -631,11 +664,11 @@ mata:
real matrix leftoverrow(data, x, y, dx, dy)
{
covered_area = sum(data)
width = covered_area / dy
leftover_x = x + width
leftover_y = y
leftover_dx = dx - width
leftover_dy = dy
width = covered_area / dy
leftover_x = x + width
leftover_y = y
leftover_dx = dx - width
leftover_dy = dy
return (leftover_x, leftover_y, leftover_dx, leftover_dy)
}
end
Expand All @@ -651,11 +684,11 @@ mata:
real matrix leftovercol(data, x, y, dx, dy)
{
covered_area = sum(data)
height = covered_area / dx
leftover_x = x
leftover_y = y + height
leftover_dx = dx
leftover_dy = dy - height
height = covered_area / dx
leftover_x = x
leftover_y = y + height
leftover_dx = dx
leftover_dy = dy - height
return (leftover_x, leftover_y, leftover_dx, leftover_dy)
}
Expand All @@ -682,21 +715,32 @@ end


*************************
// worst_ratio //
// worst_ratio //
*************************

cap mata mata drop worst_ratio()

mata:
real scalar worst_ratio(data, x, y, dx, dy)
real scalar worst_ratio(data, x, y, dx, dy, rat)
{
temp = layout(data, x, y, dx, dy)
sumval = sum(data)
minval = sumval
maxval = sumval
temp = layout(data, x, y, dx, dy)
ratiolist = J(rows(temp), 1, .)
for (i=1; i<= rows(data); i++) ratiolist[i] = max((temp[i,3] :/ temp[i,4], temp[i,4] :/ temp[i,3]))
for (i=1; i<= rows(data); i++) {
ratiolist[i] = max((temp[i,3] :/ temp[i,4], temp[i,4] :/ temp[i,3]))
if (data[i] < minval) minval = data[i]
if (data[i] > maxval) maxval = data[i]
}
return (max(ratiolist))
// alph = max(ratiolist)
// beta = sumval :* sumval :* alph
// return (max((maxval / beta, beta / minval)))
return (max(ratiolist))
}
end

Expand All @@ -709,7 +753,7 @@ end
cap mata mata drop squarify()

mata:
function squarify(data, x, y, dx, dy)
function squarify(data, x, y, dx, dy, myratio)
{
if (rows(data) == 1) return (layout(data, x, y, dx, dy))
Expand All @@ -720,7 +764,7 @@ function squarify(data, x, y, dx, dy)
i = 1
while ((i < rows(data)) & (worst_ratio(data[1 .. i], x, y, dx, dy) >= worst_ratio(data[1 .. i + 1], x, y, dx, dy))) i = i + 1
while ((i < rows(data)) & (worst_ratio(data[1 .. i], x, y, dx, dy, myratio) >= worst_ratio(data[1 .. i + 1], x, y, dx, dy, myratio))) i = i + 1
current = data[1 .. i]
remaining = data[i+1 .. rows(data)]
Expand All @@ -730,7 +774,7 @@ function squarify(data, x, y, dx, dy)
leftover_dx = leftover(current, x, y, dx, dy)[3]
leftover_dy = leftover(current, x, y, dx, dy)[4]
return (layout(current, x, y, dx, dy) \ squarify(remaining, leftover_x, leftover_y, leftover_dx, leftover_dy))
return (layout(current, x, y, dx, dy) \ squarify(remaining, leftover_x, leftover_y, leftover_dx, leftover_dy, myratio))
}
end
Expand All @@ -744,28 +788,15 @@ end
cap mata mata drop processchildren()

mata:
function processchildren(index, data, bounds, padb, padt, padl, padr)
function processchildren(index, data, bounds, padb, padt, padl, padr, myratio)
{
// if (bounds[index,.][3] - padr - bounds[index,.][1] - padl < 0) {
// xdiff = 0
// padr = padr - xdiff; padl = padl - xdiff
// }
// if (bounds[index,.][4] - padt - bounds[index,.][4] - padb < 0) {
// ydiff = 0
// padt = padt - ydiff; padb = padb - ydiff
// }
xmin = bounds[index,.][1] + padl
ymin = bounds[index,.][2] + padb
dx = bounds[index,.][3] - padl - padr
dy = bounds[index,.][4] - padb - padt
normlist = normdata(data, dx, dy)
return (squarify(normlist, xmin, ymin, dx, dy), normlist)
return (squarify(normlist, xmin, ymin, dx, dy, myratio), normlist)
}
end

Expand Down
8 changes: 4 additions & 4 deletions installation/treemap.pkg
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
v 1.1
d {bf:TREEMAP}: A Stata package for treemaps in Stata
v 1.2
d {bf:TREEMAP}: A Stata package for treemaps
d
d Requires: Stata version 15 or higher.
d
Expand All @@ -8,9 +8,9 @@ d KW: graphs
d KW: treemap
d KW: squarify
d
d Distribution-Date: 20220913
d Distribution-Date: 20220922
d
d This version: 13 Sep 2022
d This version: 25 Sep 2022
d First version: 08 Sep 2022
d License: MIT
d
Expand Down
Loading

0 comments on commit f47aa46

Please sign in to comment.