A comparison of 41 map projections by four different types of distortion. Lower is better. Data transcribed from the Natural Earth Projection.
Last active
March 2, 2019 09:44
-
-
Save mbostock/3709000 to your computer and use it in GitHub Desktop.
Map Projection Distortions
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
license: gpl-3.0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<meta charset="utf-8"> | |
<title>Map Projections</title> | |
<style> | |
svg { | |
font: 10px sans-serif; | |
} | |
.background path { | |
fill: none; | |
stroke: none; | |
stroke-width: 20px; | |
pointer-events: stroke; | |
} | |
.foreground path { | |
fill: none; | |
stroke: steelblue; | |
stroke-width: 1.5px; | |
} | |
.axis .title { | |
font-size: 11px; | |
font-weight: bold; | |
text-transform: uppercase; | |
} | |
.axis line, | |
.axis path { | |
fill: none; | |
stroke: #000; | |
shape-rendering: crispEdges; | |
} | |
.label { | |
-webkit-transition: fill 125ms linear; | |
} | |
.active .label:not(.inactive) { | |
font-weight: bold; | |
} | |
.label.inactive { | |
fill: #ccc; | |
} | |
.foreground path.inactive { | |
stroke: #ccc; | |
stroke-opacity: .5; | |
stroke-width: 1px; | |
} | |
</style> | |
<body> | |
<script src="//d3js.org/d3.v3.min.js"></script> | |
<script> | |
var margin = {top: 30, right: 40, bottom: 20, left: 200}, | |
width = 960 - margin.left - margin.right, | |
height = 500 - margin.top - margin.bottom; | |
var dimensions = [ | |
{ | |
name: "name", | |
scale: d3.scale.ordinal().rangePoints([0, height]), | |
type: String | |
}, | |
{ | |
name: "Acc. 40º 150%", | |
scale: d3.scale.linear().range([0, height]), | |
type: Number | |
}, | |
{ | |
name: "Scale", | |
scale: d3.scale.linear().range([height, 0]), | |
type: Number | |
}, | |
{ | |
name: "Areal", | |
scale: d3.scale.sqrt().range([height, 0]), | |
type: Number | |
}, | |
{ | |
name: "Angular", | |
scale: d3.scale.linear().range([height, 0]), | |
type: Number | |
} | |
]; | |
var x = d3.scale.ordinal() | |
.domain(dimensions.map(function(d) { return d.name; })) | |
.rangePoints([0, width]); | |
var line = d3.svg.line() | |
.defined(function(d) { return !isNaN(d[1]); }); | |
var yAxis = d3.svg.axis() | |
.orient("left"); | |
var svg = d3.select("body").append("svg") | |
.attr("width", width + margin.left + margin.right) | |
.attr("height", height + margin.top + margin.bottom) | |
.append("g") | |
.attr("transform", "translate(" + margin.left + "," + margin.top + ")"); | |
var dimension = svg.selectAll(".dimension") | |
.data(dimensions) | |
.enter().append("g") | |
.attr("class", "dimension") | |
.attr("transform", function(d) { return "translate(" + x(d.name) + ")"; }); | |
d3.tsv("projections.tsv", function(error, data) { | |
if (error) throw error; | |
dimensions.forEach(function(dimension) { | |
dimension.scale.domain(dimension.type === Number | |
? d3.extent(data, function(d) { return +d[dimension.name]; }) | |
: data.map(function(d) { return d[dimension.name]; }).sort()); | |
}); | |
svg.append("g") | |
.attr("class", "background") | |
.selectAll("path") | |
.data(data) | |
.enter().append("path") | |
.attr("d", draw); | |
svg.append("g") | |
.attr("class", "foreground") | |
.selectAll("path") | |
.data(data) | |
.enter().append("path") | |
.attr("d", draw); | |
dimension.append("g") | |
.attr("class", "axis") | |
.each(function(d) { d3.select(this).call(yAxis.scale(d.scale)); }) | |
.append("text") | |
.attr("class", "title") | |
.attr("text-anchor", "middle") | |
.attr("y", -9) | |
.text(function(d) { return d.name; }); | |
// Rebind the axis data to simplify mouseover. | |
svg.select(".axis").selectAll("text:not(.title)") | |
.attr("class", "label") | |
.data(data, function(d) { return d.name || d; }); | |
var projection = svg.selectAll(".axis text,.background path,.foreground path") | |
.on("mouseover", mouseover) | |
.on("mouseout", mouseout); | |
function mouseover(d) { | |
svg.classed("active", true); | |
projection.classed("inactive", function(p) { return p !== d; }); | |
projection.filter(function(p) { return p === d; }).each(moveToFront); | |
} | |
function mouseout(d) { | |
svg.classed("active", false); | |
projection.classed("inactive", false); | |
} | |
function moveToFront() { | |
this.parentNode.appendChild(this); | |
} | |
}); | |
function draw(d) { | |
return line(dimensions.map(function(dimension) { | |
return [x(dimension.name), dimension.scale(d[dimension.name])]; | |
})); | |
} | |
</script> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Acc. 40º 150% | Scale | Areal | Angular | name | |
---|---|---|---|---|---|
87.7 | 0.29 | 0.37 | 18.25 | Eckert III | |
87.5 | 0.25 | 0.19 | 20.54 | Natural Earth | |
87.4 | 0.27 | 0.17 | 24.2 | Winkel II | |
86.5 | 0.23 | 0.28 | 19.15 | Kavraisky VII | |
85 | 0.26 | 0.18 | 23.28 | Winkel Tripel | |
84.3 | 0.27 | 0.19 | 21.27 | Robinson | |
83.2 | 0.25 | 0.43 | 16.14 | Fahey | |
81.9 | 0.36 | 0 | 28.73 | Eckert IV | |
81.8 | 0.26 | 0.24 | 22.31 | Hölzel | |
80.4 | 0.26 | 0.34 | 20.41 | Wagner VI | |
80 | 0.3 | 0.29 | 23.47 | Eckert V | |
78.4 | 0.32 | 0.07 | 26.38 | McBryde–Thomas Flat-Pole Sine (No. 2) | |
78.1 | 0.29 | 0.23 | 25.8 | Winkel I | |
77.9 | 0.28 | 0.3 | 22.68 | Wagner III | |
76.5 | 0.32 | 0.12 | 26.88 | Wagner II | |
76.2 | 0.31 | 0.25 | NaN | Denoyer Semi-elliptical | |
75.2 | 0.3 | 0.31 | 24.31 | Putnins P5' | |
74.3 | 0.29 | 0.57 | 16.84 | Equidistant Cylindrical (Plate Carrée) | |
74.1 | 0.38 | 0 | 30.56 | Kavraisky V | |
74 | 0.37 | 0 | 30.71 | Wagner VII | |
72.4 | 0.39 | 0 | 31.54 | Putnins P4' | |
71.9 | 0.57 | 0 | 30.9 | Cylindrical Equal-Area | |
70.6 | 0.39 | 0 | 32.28 | Mollweide | |
70.5 | 0.29 | 0.51 | 20.36 | Ginzburg VIII (TsNIIGAiK 1944) | |
70.2 | 0.43 | 0 | 30.9 | Nell–Hammer | |
69.1 | 0.39 | 0.1 | 30.79 | Putnins P1 | |
68.1 | 0.36 | 0.23 | 30.17 | Aitoff | |
68.1 | 0.36 | 0.29 | 30.3 | Eckert I | |
67 | 0.44 | 0 | 33.33 | Foucaut Sinusoidal | |
63.7 | 0.44 | 0 | 35.2 | Boggs Eumorphic | |
63 | 0.45 | 0 | 35.5 | Eckert–Greifendorff | |
62.9 | 0.39 | 1.3 | 7.63 | Miller Cylindrical I | |
62.4 | 0.47 | 0 | 36 | Quartic Authalic | |
61.7 | 0.35 | 1.05 | 10.06 | Larrivée | |
60.3 | 0.48 | 0 | 36.99 | Craster Parabolic (Putnins P4) | |
58.9 | 0.46 | 0 | 36.39 | Goode Homolosine | |
57.4 | 0.41 | 1.46 | 7.75 | van der Grinten (I) | |
57.4 | 0.57 | 4.79 | 0 | Mercator | |
57.1 | 0.51 | 0 | 39.01 | Sinusoidal | |
49 | 0.3 | 0.73 | 10.62 | Gall (Gall Stereographic) | |
42.2 | 0.74 | 0 | 52.39 | Foucaut |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment