A comparison of 41 map projections by four different types of distortion. Lower is better. Data transcribed from the Natural Earth Projection.
| <!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> |
| 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