Skip to content

Instantly share code, notes, and snippets.

@jeremiaheb
Last active February 5, 2016 20:06
Show Gist options
  • Save jeremiaheb/f9c387c19477371f2a46 to your computer and use it in GitHub Desktop.
Save jeremiaheb/f9c387c19477371f2a46 to your computer and use it in GitHub Desktop.

Circle Pack visual of RVC Biomass

{
"name": "perciformes",
"children": [
{
"name": "Acanthuridae",
"children": [
{
"name": "Acanthurus",
"children": [
{
"name": "bahianus",
"abundance": 14725000,
"biomass": 1120800,
"occurrence": 0.82815
},
{
"name": "chirurgus",
"abundance": 6864100,
"biomass": 1134700,
"occurrence": 0.50017
},
{
"name": "coeruleus",
"abundance": 13802000,
"biomass": 1567600,
"occurrence": 0.79202
}
]
}
]
},
{
"name": "Aulostomidae",
"children": [
{
"name": "Aulostomus",
"children": [
{
"name": "maculatus",
"abundance": 425080,
"biomass": 61049,
"occurrence": 0.14389
}
]
}
]
},
{
"name": "Carangidae",
"children": [
{
"name": "Caranx",
"children": [
{
"name": "bartholomaei",
"abundance": 2457500,
"biomass": 1895600,
"occurrence": 0.051212
},
{
"name": "ruber",
"abundance": 12777000,
"biomass": 880730,
"occurrence": 0.37117
}
]
}
]
},
{
"name": "Chaetodontidae",
"children": [
{
"name": "Chaetodon",
"children": [
{
"name": "capistratus",
"abundance": 4722300,
"biomass": 9128.1,
"occurrence": 0.50266
},
{
"name": "ocellatus",
"abundance": 3159900,
"biomass": 141770,
"occurrence": 0.45888
},
{
"name": "striatus",
"abundance": 469420,
"biomass": 18046,
"occurrence": 0.11195
}
]
}
]
},
{
"name": "Gobiidae",
"children": [
{
"name": "Coryphopterus",
"children": [
{
"name": "dicrus",
"abundance": 281590,
"biomass": 171.1,
"occurrence": 0.07821
},
{
"name": "glaucofraenum",
"abundance": 9602500,
"biomass": 4440.1,
"occurrence": 0.5579
},
{
"name": "personatus",
"abundance": 101500000,
"biomass": 15935,
"occurrence": 0.3657
}
]
},
{
"name": "Elacatinus",
"children": [
{
"name": "oceanops",
"abundance": 1148400,
"biomass": 503.14,
"occurrence": 0.1693
}
]
},
{
"name": "Gnatholepis",
"children": [
{
"name": "thompsoni",
"abundance": 1033500,
"biomass": 669.67,
"occurrence": 0.17772
}
]
}
]
},
{
"name": "Haemulidae",
"children": [
{
"name": "Anisotremus",
"children": [
{
"name": "surinamensis",
"abundance": 103490,
"biomass": 103110,
"occurrence": 0.036349
},
{
"name": "virginicus",
"abundance": 2998000,
"biomass": 875660,
"occurrence": 0.33089
}
]
},
{
"name": "Haemulon",
"children": [
{
"name": "aurolineatum",
"abundance": 46490000,
"biomass": 576040,
"occurrence": 0.14001
},
{
"name": "carbonarium",
"abundance": 751700,
"biomass": 115410,
"occurrence": 0.061755
},
{
"name": "chrysargyreum",
"abundance": 1437900,
"biomass": 46220,
"occurrence": 0.030468
},
{
"name": "flavolineatum",
"abundance": 15514000,
"biomass": 666930,
"occurrence": 0.38724
},
{
"name": "macrostomum",
"abundance": 76919,
"biomass": 21787,
"occurrence": 0.021043
},
{
"name": "parra",
"abundance": 4509600,
"biomass": 1211500,
"occurrence": 0.057246
},
{
"name": "sciurus",
"abundance": 11038000,
"biomass": 1960900,
"occurrence": 0.30514
}
]
}
]
},
{
"name": "Holocentridae",
"children": [
{
"name": "Holocentrus",
"children": [
{
"name": "adscensionis",
"abundance": 287720,
"biomass": 59454,
"occurrence": 0.088384
},
{
"name": "rufus",
"abundance": 200650,
"biomass": 37258,
"occurrence": 0.043758
}
]
}
]
},
{
"name": "Kyphosidae",
"children": [
{
"name": "Kyphosus",
"children": [
{
"name": "sectatrix",
"abundance": 1549700,
"biomass": 936310,
"occurrence": 0.06859
}
]
}
]
},
{
"name": "Labridae",
"children": [
{
"name": "Bodianus",
"children": [
{
"name": "rufus",
"abundance": 1081600,
"biomass": 147730,
"occurrence": 0.24772
}
]
},
{
"name": "Clepticus",
"children": [
{
"name": "parrae",
"abundance": 15316000,
"biomass": 182240,
"occurrence": 0.15925
}
]
},
{
"name": "Halichoeres",
"children": [
{
"name": "bivittatus",
"abundance": 24867000,
"biomass": 113970,
"occurrence": 0.6966
},
{
"name": "garnoti",
"abundance": 17066000,
"biomass": 106700,
"occurrence": 0.75467
},
{
"name": "maculipinna",
"abundance": 9873200,
"biomass": 41219,
"occurrence": 0.56652
},
{
"name": "radiatus",
"abundance": 1311700,
"biomass": 31014,
"occurrence": 0.26992
}
]
},
{
"name": "Lachnolaimus",
"children": [
{
"name": "maximus",
"abundance": 6172400,
"biomass": 2160100,
"occurrence": 0.64246
}
]
},
{
"name": "Thalassoma",
"children": [
{
"name": "bifasciatum",
"abundance": 68466000,
"biomass": 150080,
"occurrence": 0.9257
}
]
}
]
},
{
"name": "Lutjanidae",
"children": [
{
"name": "Lutjanus",
"children": [
{
"name": "analis",
"abundance": 1032700,
"biomass": 1397200,
"occurrence": 0.22238
},
{
"name": "apodus",
"abundance": 2001800,
"biomass": 457020,
"occurrence": 0.11759
},
{
"name": "griseus",
"abundance": 6435900,
"biomass": 1776200,
"occurrence": 0.21608
},
{
"name": "mahogoni",
"abundance": 116960,
"biomass": 33272,
"occurrence": 0.016541
}
]
},
{
"name": "Ocyurus",
"children": [
{
"name": "chrysurus",
"abundance": 18828000,
"biomass": 2999600,
"occurrence": 0.61185
}
]
}
]
},
{
"name": "Monacanthidae",
"children": [
{
"name": "Aluterus",
"children": [
{
"name": "scriptus",
"abundance": 387570,
"biomass": 55533,
"occurrence": 0.094048
}
]
}
]
},
{
"name": "Mullidae",
"children": [
{
"name": "Mulloidichthys",
"children": [
{
"name": "martinicus",
"abundance": 219940,
"biomass": 51715,
"occurrence": 0.024437
}
]
},
{
"name": "Pseudupeneus",
"children": [
{
"name": "maculatus",
"abundance": 2017300,
"biomass": 126230,
"occurrence": 0.28538
}
]
}
]
},
{
"name": "Ostraciidae",
"children": [
{
"name": "Lactophrys",
"children": [
{
"name": "triqueter",
"abundance": 258580,
"biomass": 40510,
"occurrence": 0.11589
}
]
}
]
},
{
"name": "Pomacanthidae",
"children": [
{
"name": "Holacanthus",
"children": [
{
"name": "ciliaris",
"abundance": 1663800,
"biomass": 630980,
"occurrence": 0.37755
},
{
"name": "tricolor",
"abundance": 2868400,
"biomass": 219210,
"occurrence": 0.39116
}
]
},
{
"name": "Pomacanthus",
"children": [
{
"name": "arcuatus",
"abundance": 4211000,
"biomass": 2773700,
"occurrence": 0.58967
},
{
"name": "paru",
"abundance": 959740,
"biomass": 714070,
"occurrence": 0.27668
}
]
}
]
},
{
"name": "Pomacentridae",
"children": [
{
"name": "Abudefduf",
"children": [
{
"name": "saxatilis",
"abundance": 4706000,
"biomass": 160240,
"occurrence": 0.19065
}
]
},
{
"name": "Chromis",
"children": [
{
"name": "cyanea",
"abundance": 11405000,
"biomass": 50847,
"occurrence": 0.37458
},
{
"name": "multilineata",
"abundance": 2912700,
"biomass": 27523,
"occurrence": 0.11215
},
{
"name": "scotti",
"abundance": 2589400,
"biomass": 2819.4,
"occurrence": 0.096457
}
]
},
{
"name": "Microspathodon",
"children": [
{
"name": "chrysurus",
"abundance": 499430,
"biomass": 21103,
"occurrence": 0.086388
}
]
},
{
"name": "Stegastes",
"children": [
{
"name": "adustus",
"abundance": 831090,
"biomass": 7160.8,
"occurrence": 0.12409
},
{
"name": "leucostictus",
"abundance": 899840,
"biomass": 5436.1,
"occurrence": 0.21971
},
{
"name": "partitus",
"abundance": 82492000,
"biomass": 139270,
"occurrence": 0.88548
},
{
"name": "planifrons",
"abundance": 1600700,
"biomass": 14169,
"occurrence": 0.19883
},
{
"name": "variabilis",
"abundance": 3625400,
"biomass": 16833,
"occurrence": 0.49671
}
]
}
]
},
{
"name": "Scaridae",
"children": [
{
"name": "Scarus",
"children": [
{
"name": "coelestinus",
"abundance": 414800,
"biomass": 610650,
"occurrence": 0.079202
},
{
"name": "coeruleus",
"abundance": 1858100,
"biomass": 1349000,
"occurrence": 0.24884
},
{
"name": "guacamaia",
"abundance": 801400,
"biomass": 1328700,
"occurrence": 0.15697
},
{
"name": "iseri",
"abundance": 39752000,
"biomass": 444050,
"occurrence": 0.83378
},
{
"name": "taeniopterus",
"abundance": 2143000,
"biomass": 229220,
"occurrence": 0.23338
},
{
"name": "vetula",
"abundance": 245210,
"biomass": 148660,
"occurrence": 0.068505
}
]
},
{
"name": "Sparisoma",
"children": [
{
"name": "aurofrenatum",
"abundance": 29723000,
"biomass": 990130,
"occurrence": 0.95077
},
{
"name": "chrysopterum",
"abundance": 1298800,
"biomass": 364060,
"occurrence": 0.28755
},
{
"name": "rubripinne",
"abundance": 1445600,
"biomass": 518280,
"occurrence": 0.22942
},
{
"name": "viride",
"abundance": 9826500,
"biomass": 2019500,
"occurrence": 0.65822
}
]
}
]
},
{
"name": "Scombridae",
"children": [
{
"name": "Scomberomorus",
"children": [
{
"name": "regalis",
"abundance": 210930,
"biomass": 210780,
"occurrence": 0.078527
}
]
}
]
},
{
"name": "Serranidae",
"children": [
{
"name": "Cephalopholis",
"children": [
{
"name": "cruentata",
"abundance": 2623000,
"biomass": 204460,
"occurrence": 0.44247
}
]
},
{
"name": "Hypoplectrus",
"children": [
{
"name": "unicolor",
"abundance": 1753700,
"biomass": 15117,
"occurrence": 0.38397
}
]
},
{
"name": "Mycteroperca",
"children": [
{
"name": "bonaci",
"abundance": 206540,
"biomass": 642310,
"occurrence": 0.09011
}
]
},
{
"name": "Serranus",
"children": [
{
"name": "tigrinus",
"abundance": 1462800,
"biomass": 8530,
"occurrence": 0.35105
}
]
}
]
},
{
"name": "Sphyraenidae",
"children": [
{
"name": "Sphyraena",
"children": [
{
"name": "barracuda",
"abundance": 315450,
"biomass": 1182400,
"occurrence": 0.072671
}
]
}
]
},
{
"name": "Tetraodontidae",
"children": [
{
"name": "Canthigaster",
"children": [
{
"name": "rostrata",
"abundance": 3682200,
"biomass": 9328.1,
"occurrence": 0.55068
}
]
}
]
}
]
}

Circle packing visual.

<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<script src="//d3js.org/d3.v3.min.js" charset="utf-8"></script></script>
<style type="text/css">
html, body {
<!--overflow: scroll;-->
margin: 0;
font-family: "Helvetica Neue", Helvetica;
}
#leafName {
position: absolute;
width: 760px;
text-align: center;
font-family: "Helvetica Neue", Helvetica;
font-size: 25px;
}
#selectionName {
position: absolute;
width: 760px;
text-align: center;
font-family: "Helvetica Neue", Helvetica;
font-size: 25px;
color: #002F2F;
}
text {
font-size: 15px;
pointer-events: none;
}
text.parent {
fill: #002F2F;
}
circle {
<!--fill: #ccc;-->
stroke: #999;
pointer-events: all;
}
circle.parent {
<!--fill: #1f77b4;-->
fill-opacity: .1;
stroke: steelblue;
}
circle.parent:hover {
stroke: #ff7f0e;
stroke-width: .5px;
}
circle.child {
<!--pointer-events: none;-->
}
.bar {
fill: steelblue;
}
<!--.bar:hover {-->
<!--fill: brown;-->
<!--}-->
.axis {
font: 10px sans-serif;
}
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.x.axis path {
}
</style>
</head>
<body>
<p id="leafName"> </p>
<script type="text/javascript">
var w = 760,
h = 565,
r = 760,
x = d3.scale.linear().range([0, r]),
y = d3.scale.linear().range([0, r]),
node,
root;
var pack = d3.layout.pack()
.padding(1)
.size([r,r])
.value(function(d) { return d.abundance; });
var vis = d3.select("body").insert("svg:svg", "h2")
.attr("width", w)
.attr("height", w)
.append("svg:g")
.attr("transform", "translate(" + (w - r) / 2 + "," + (w - r) / 2 + ")");
var buttonData = ["Abundance", "Biomass", "Occurrence"];
var buttonDiv = d3.select("body").append("svg")
.attr("width", 120)
.attr("height", 760);
var buttons = buttonDiv.selectAll(".updateButton")
.data(buttonData)
.enter()
.append('g')
.attr("class", "updateButton")
.on("click", function(d, i) {
dataSource = i;
updateVis();
});
buttons.append("rect")
.attr("x", 5)
.attr("y", function(d, i) { return (760 - (i + 1)*30); })
.attr("width", 98)
.attr("height", 25)
.attr("ry", 5)
.style("stroke", "#787878")
.style("fill", "tan");
buttons.append("text")
.attr("x", 55)
.attr("y", function(d, i) { return (772 - (i + 1)*30); })
.attr("dy", "0.35em")
.style("text-anchor", "middle")
.style("font-size", "15px")
.text(function(d) { return d; });
var color = d3.scale.ordinal()
.domain(["0", "1", "2", "3"])
.range(["#FCFFF5","#D1DBBD","#91AA9D", "#3E606F"]);
d3.json("BioAbunOcc.json", function(data) {
node = root = data;
var nodes = pack.nodes(root);
vis.selectAll("circle")
.data(nodes)
.enter().append("svg:circle")
.attr("class", function(d) { return d.children ? "parent" : "child"; })
.attr("id", function(d) { return d.name })
.attr("cx", function(d) { return d.x; })
.attr("cy", function(d) { return d.y; })
.attr("r", function(d) { return d.r; })
.style("fill", function(d) { return color(d.depth); })
.style("fill-opacity", ".3")
.on("click", function(d) { if (d.depth !== 3) {
zoom(d),
d3.event.stopPropagation();
}
else {
zoom(d.parent),
addSpeciesData(d.name);
d3.event.stopPropagation();}
})
.on("mouseover", function(d){ d.depth == 3 ?
d3.select("#leafName").text(d.parent.name + " " + d.name) : null})
.on("mouseout", function(d){ d.depth == 3 ?
d3.select("#leafName").text(null) : null});
vis.selectAll("text")
.data(nodes)
.enter().append("svg:text")
.attr("class", function(d) { return d.children ? "parent" : "child"; })
.attr("x", function(d) { return d.x; })
.attr("y", function(d) { return d.y; })
.attr("dy", ".35em")
.attr("text-anchor", "middle")
.style("opacity", function(d) { return d.depth ==1 ? 1 : 0; })
.text(function(d) {
return d.name;
});
d3.select(window).on("click", function() { zoom(root); });
zoom(root);
});
function zoom(d, i) {
var focus0 = focus; focus = d;
var k = r / d.r / 2;
x.domain([d.x - d.r, d.x + d.r]);
y.domain([d.y - d.r, d.y + d.r]);
var t = vis.transition()
.duration(1550);
t.selectAll("circle")
.attr("cx", function(d) { return x(d.x); })
.attr("cy", function(d) { return y(d.y); })
.attr("r", function(d) { return k * d.r; });
// updateCounter is a hacky way to determine when transition is finished
var updateCounter = 0;
t.selectAll("text")
.style("fill-opacity", function(d) { return d.parent === focus ? 1 : 0; })
<!--.style("display", function(d) { return d.parent === focus ? null : "none";})-->
.attr("x", function(d) { return x(d.x); })
.attr("y", function(d) { return y(d.y); })
.each(function(d, i) {
updateCounter++;
})
.each("end", function(d, i) {
updateCounter--;
if (updateCounter == 0) {
adjustLabels(k);
}
});
node = d;
}
function adjustLabels(k) {
vis.selectAll("text")
.style("opacity", function(d) {
return k * d.r > 20 ? 1 : 0;
})
.text(function(d) {
return d.name;
})
.filter(function(d) {
d.tw = this.getComputedTextLength();
return (Math.PI*(k*d.r)/2) < d.tw;
})
.each(function(d) {
var proposedLabel = d.name;
var proposedLabelArray = proposedLabel.split('');
while ((d.tw > (Math.PI*(k*d.r)/2) && proposedLabelArray.length)) {
// pull out 3 chars at a time to speed things up (one at a time is too slow)
proposedLabelArray.pop();proposedLabelArray.pop(); proposedLabelArray.pop();
if (proposedLabelArray.length===0) {
proposedLabel = "";
} else {
proposedLabel = proposedLabelArray.join('') + "..."; // manually truncate with ellipsis
}
d3.select(this).text(proposedLabel);
d.tw = this.getComputedTextLength();
}
});
}
function updateVis() {
zoom(root);
if (dataSource == 0)
pack.value(function(d) { return d.abundance; }),
d3.select("#selectionName").text("Abundance");
if (dataSource == 1)
pack.value(function(d) { return d.biomass; }),
d3.select("#selectionName").text("Biomass");
if (dataSource == 2)
pack.value(function(d) { return d.occurrence; }),
d3.select("#selectionName").text("Occurrence");
var data1 = pack.nodes(node);
};
function addSpeciesData(spp) {
d3.select(".lengthFreq").remove();
var margin = {top: 20, right: 20, bottom: 60, left: 80},
width = 600 - margin.left - margin.right,
height = 400 - margin.top - margin.bottom;
var x = d3.scale.ordinal()
.rangeRoundBands([0, width], .25);
var y = d3.scale.linear()
.range([height, 0]);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(y)
.orient("left")
.ticks(10, "%");
var svg = d3.select("body").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.attr("class", "lengthFreq")
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
d3.json("sppHist.json", function(error, json) {
if (error) throw error;
var data = json[spp]
var sum = d3.sum(data, function(d){ return d.frequency});
x.domain(data.map(function(d) { return d.LengthCat; }));
y.domain([0, d3.max(data, function(d) { return (d.frequency / sum); })]);
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis)
.selectAll("text")
.style("display", function(d,i) { return i % 2 === 0 ? null : "none" });
svg.append("g")
.attr("class", "y axis")
.call(yAxis);
svg.selectAll(".bar")
.data(data)
.enter().append("rect")
.attr("class", "bar")
.attr("x", function(d) { return x(d.LengthCat); })
.attr("width", x.rangeBand())
.attr("y", function(d) { return y(d.frequency/sum); })
.attr("height", function(d) { return height - y(d.frequency/sum); });
svg.append("text")
.attr("text-anchor", "middle")
.attr("transform", "translate("+ (-margin.left/1.5) +","+(height/2)+")rotate(-90)")
.text(spp + " Frequency");
svg.append("text")
.attr("text-anchor", "middle")
.attr("transform", "translate("+ (width/2) +","+(height+(margin.bottom/1.5))+")")
.text("Length(cm)");
});
function type(d) {
d.frequency = +d.frequency;
return d;
}
}
</script>
<p id="selectionName"> Abundance </p>
</body>
</html>
{
"apodus": [
{
"LengthCat":2.5,
"frequency":1869
},
{
"LengthCat":7.5,
"frequency":1547
},
{
"LengthCat":12.5,
"frequency":19532
},
{
"LengthCat":17.5,
"frequency":55766
},
{
"LengthCat":22.5,
"frequency":95843
},
{
"LengthCat":27.5,
"frequency":190178
},
{
"LengthCat":32.5,
"frequency":296668
},
{
"LengthCat":37.5,
"frequency":206164
},
{
"LengthCat":42.5,
"frequency":149298
},
{
"LengthCat":47.5,
"frequency":82772
},
{
"LengthCat":52.5,
"frequency":64242
},
{
"LengthCat":57.5,
"frequency":32144
},
{
"LengthCat":62.5,
"frequency":21537
},
{
"LengthCat":67.5,
"frequency":11023
},
{
"LengthCat":72.5,
"frequency":741
},
{
"LengthCat":77.5,
"frequency":0
},
{
"LengthCat":82.5,
"frequency":0
}
],
"analis": [
{
"LengthCat":2.5,
"frequency":0
},
{
"LengthCat":7.5,
"frequency":8438
},
{
"LengthCat":12.5,
"frequency":195758
},
{
"LengthCat":17.5,
"frequency":851241
},
{
"LengthCat":22.5,
"frequency":1278078
},
{
"LengthCat":27.5,
"frequency":1019841
},
{
"LengthCat":32.5,
"frequency":619812
},
{
"LengthCat":37.5,
"frequency":188076
},
{
"LengthCat":42.5,
"frequency":61373
},
{
"LengthCat":47.5,
"frequency":29897
},
{
"LengthCat":52.5,
"frequency":3193
},
{
"LengthCat":57.5,
"frequency":442
},
{
"LengthCat":62.5,
"frequency":0
},
{
"LengthCat":67.5,
"frequency":0
},
{
"LengthCat":72.5,
"frequency":0
},
{
"LengthCat":77.5,
"frequency":0
},
{
"LengthCat":82.5,
"frequency":0
}
]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment