Skip to content

Instantly share code, notes, and snippets.

@nielshanson
Last active August 29, 2015 14:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nielshanson/23bd4b2ecf9d44ba1a8f to your computer and use it in GitHub Desktop.
Save nielshanson/23bd4b2ecf9d44ba1a8f to your computer and use it in GitHub Desktop.
World Map

About the plot

World map of locations of a selection of environmental metagenoems contained in the Integrated Microbial Genomes System (IMG/M), a genome browsing and annotation platform developed by the U.S. Department of Energy (DOE)-Joint Genome Institute (JGI). Points scaled by sequencing depth and colored based on broad categories of aquatic (blue), terrestrial (green), and air (grey). This work is expands upon the excellent Let's Make a Map tutorial by Mike Bostock, utilizing the Geo Projections and Geo Paths generators build into D3.js. The projection being used is the Kavrayskiy_VII.

Cartographic information is the 50m Admin 0 - Details dataset, obtained from Natural Earth. The tutorial goes into great detail of how to create a GeoJSON.

Usage

To simply place points on the map, the input csv file need only have two columns named latitude and longitude. However, the tool-tip assumes additional columns name, fillKey, mbs, and project.

SVG Crowbar is a great tool for extracting SVG files from d3 plots for downstream purposes.

/* CSS goes here. */
/*path {
fill: none;
stroke: #000;
stroke-linejoin: round;
stroke-linecap: round;
}
*/
/* country boundary */
.land {
fill: #AAAAAA;
}
.border {
fill: none;
stroke: #FBFBFB;
stroke-linejoin: round;
stroke-linecap: round;
}
.fill {
fill: #fff;
}
.stroke {
fill: none;
stroke: #000;
stroke-width: 3px;
}
.bubble {
fill-opacity: .7;
stroke: #fff;
stroke-width: .5px;
}
.graticule {
fill: none;
stroke: #777;
stroke-width: .5px;
stroke-opacity: .5;
}
body {
font-family: Arial,Helvetica Neue,Helvetica,sans-serif;
font-size: 10px;
}
/* Hover info */
.hoverinfo {
padding: 4px;
border-radius: 1px;
background-color: #FFF;
box-shadow: 1px 1px 5px #CCC;
font-size: 10px;
border: 1px solid #CCC;
}
.hoverinfo hr {
border:1px dotted #CCC;
}
var width = 960,
height = 550;
var svg = d3.select("#figure").append("svg")
.attr("width", width)
.attr("height", height);
// Mapping colors
var colors = {
soil: '#00441b',
Soil: '#00441b',
sediment: '#00441b',
air: '#737373',
water: '#4292c6',
Thermal_springs: '#6baed6',
Non_marine_Saline_and_Alkaline: '#2171b5',
Marine: '#08519c',
Freshwater: '#4292c6',
Deep_subsurface: '#41ab5d',
test: "red"
};
var my_projection = d3.geo.kavrayskiy7()
.scale(170)
//.rotate([-50,90])
.translate([width / 2, height / 2])
//.clipAngle(90)
.precision(.1);
var path = d3.geo.path()
.projection(my_projection);
var tooltip = d3.select("body")
.append("div")
.style("position", "absolute")
.style("z-index", "10")
.attr("class", "hoverinfo")
.style("visibility", "hidden");
var graticule = d3.geo.graticule();
svg.append("defs").append("path")
.datum({type: "Sphere"})
.attr("id", "sphere")
.attr("d", path);
svg.append("use")
.attr("class", "stroke")
.attr("xlink:href", "#sphere");
svg.append("use")
.attr("class", "fill")
.attr("xlink:href", "#sphere");
// add graticules
svg.append("path")
.datum(graticule)
.attr("class", "graticule")
.attr("d", path);
// display the world
d3.json("world.json", function(error, world) {
if (error) return console.error(error);
var subunits = topojson.feature(world, world.objects.subunits);
// path generator
var path = d3.geo.path()
.projection(my_projection);
// Styling polygons
svg.selectAll(".subunit")
.data(subunits.features)
.enter().append("path")
//.attr("class", function(d) { return "subunit " + d.id; })
.attr("class", "land")
.attr("d", path);
// display boundaries
svg.append("path")
.datum(topojson.mesh(world, world.objects.subunits, function(a, b) { return a !== b }))
.attr("d", path)
.attr("class", "border");
// parse the bubble data
d3.text("https://cdn.rawgit.com/nielshanson/d3/master/data/imgm_bubble_data.csv", function(text) {
var bubble_data = d3.csv.parse(text);
plot_bubbles(bubble_data);
});
});
// bubble radius
var bubble_radius = d3.scale.sqrt()
.domain([0, 100000])
.range([2.5, 20]);
// function to create a tool-tip message
function create_tooltip_message(bubble_data) {
message = "Name: " + bubble_data.name + "<br/> Class: " + bubble_data.fillKey + "<br/> Lat: " + bubble_data.latitude + " Long: " + bubble_data.longitude + "<br/> Sequencing: " + bubble_data.mbs + " Mbs" + "<br/>" + "Project: " + bubble_data.project;
return message;
}
// small function generate, scale and color the circles given the input [lat, long]
function plot_bubbles(bubble_data) {
// plot circles
svg.append("g")
.attr("class", "bubble")
.selectAll("circle")
.data(bubble_data)
.enter().append("circle")
.attr("transform", function(d) {
dat = [d.longitude, d.latitude];
return "translate(" + my_projection(dat) + ")";
})
.attr("r", function(d) {
return bubble_radius(d.mbs);
})
.attr("fill", function(d) { return colors[d.fillKey];})
.on("mouseover", function(d){
tooltip.html(create_tooltip_message(d));
return tooltip.style("visibility", "visible");
})
.on("mousemove", function(){
return tooltip.style("top",(d3.event.pageY-10)+"px").style("left",(d3.event.pageX+10)+"px");
})
.on("mouseout", function(){
return tooltip.style("visibility", "hidden");
});
}
<html lang="en">
<head>
<title>d3-worldmap</title>
</head>
<body>
<div class="container">
<div id="figure"></div>
</div>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="http://d3js.org/d3.geo.projection.v0.min.js"></script>
<script src="http://d3js.org/topojson.v1.min.js"></script>
<script>
d3.select(self.frameElement).style("height", "560px");
</script>
<link href="d3_worldmap.css" type="text/css" rel="stylesheet"/>
<script src="d3_worldmap.js"></script>
</body>
Display the source blob
Display the rendered blob
Raw
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment