diff --git a/draftlogs/7731_add.md b/draftlogs/7731_add.md
new file mode 100644
index 00000000000..ecb42e372fb
--- /dev/null
+++ b/draftlogs/7731_add.md
@@ -0,0 +1 @@
+- Update USA location lookup for `scattergeo` and `choropleth` traces to use both location names and abbreviations [[7731](https://github.com/plotly/plotly.js/pull/7731)]
diff --git a/src/lib/geo_location_utils.js b/src/lib/geo_location_utils.js
index e15659f8f45..55338602fd8 100644
--- a/src/lib/geo_location_utils.js
+++ b/src/lib/geo_location_utils.js
@@ -11,22 +11,23 @@ var loggers = require('./loggers');
var isPlainObject = require('./is_plain_object');
var nestedProperty = require('./nested_property');
var polygon = require('./polygon');
+const { usaLocationAbbreviations, usaLocationList } = require('./usa_location_names');
// make list of all country iso3 ids from at runtime
var countryIds = Object.keys(countryRegex);
var locationmodeToIdFinder = {
'ISO-3': identity,
- 'USA-states': identity,
+ 'USA-states': usaLocationToAbbreviation,
'country names': countryNameToISO3
};
function countryNameToISO3(countryName) {
- for(var i = 0; i < countryIds.length; i++) {
+ for (var i = 0; i < countryIds.length; i++) {
var iso3 = countryIds[i];
var regex = new RegExp(countryRegex[iso3]);
- if(regex.test(countryName.trim().toLowerCase())) return iso3;
+ if (regex.test(countryName.trim().toLowerCase())) return iso3;
}
loggers.log('Unrecognized country name: ' + countryName + '.');
@@ -34,15 +35,26 @@ function countryNameToISO3(countryName) {
return false;
}
-function locationToFeature(locationmode, location, features) {
- if(!location || typeof location !== 'string') return false;
+function usaLocationToAbbreviation(loc) {
+ loc = loc.trim();
+ const abbreviation = usaLocationAbbreviations.has(loc.toUpperCase())
+ ? loc.toUpperCase()
+ : usaLocationList[loc.toLowerCase()];
+
+ if (abbreviation) return abbreviation;
+
+ loggers.log('Unrecognized US location: ' + loc + '.');
+
+ return false;
+}
- var locationId = locationmodeToIdFinder[locationmode](location);
- var filteredFeatures;
- var f, i;
+function locationToFeature(locationmode, location, features) {
+ if (!location || typeof location !== 'string') return false;
- if(locationId) {
- if(locationmode === 'USA-states') {
+ const locationId = locationmodeToIdFinder[locationmode](location);
+ if (locationId) {
+ let filteredFeatures;
+ if (locationmode === 'USA-states') {
// Filter out features out in USA
//
// This is important as the Natural Earth files
@@ -50,25 +62,18 @@ function locationToFeature(locationmode, location, features) {
// which have some overlay in their two-letter ids. For example,
// 'WA' is used for both Washington state and Western Australia.
filteredFeatures = [];
- for(i = 0; i < features.length; i++) {
- f = features[i];
- if(f.properties && f.properties.gu && f.properties.gu === 'USA') {
- filteredFeatures.push(f);
- }
+ for (const f of features) {
+ if (f?.properties?.gu === 'USA') filteredFeatures.push(f);
}
} else {
filteredFeatures = features;
}
- for(i = 0; i < filteredFeatures.length; i++) {
- f = filteredFeatures[i];
- if(f.id === locationId) return f;
+ for (const f of filteredFeatures) {
+ if (f.id === locationId) return f;
}
- loggers.log([
- 'Location with id', locationId,
- 'does not have a matching topojson feature at this resolution.'
- ].join(' '));
+ loggers.log(`Location with id ${locationId} does not have a matching topojson feature at this resolution.`);
}
return false;
@@ -83,13 +88,13 @@ function feature2polygons(feature) {
var appendPolygon, j, k, m;
function doesCrossAntiMerdian(pts) {
- for(var l = 0; l < pts.length - 1; l++) {
- if(pts[l][0] > 0 && pts[l + 1][0] < 0) return l;
+ for (var l = 0; l < pts.length - 1; l++) {
+ if (pts[l][0] > 0 && pts[l + 1][0] < 0) return l;
}
return null;
}
- if(loc === 'RUS' || loc === 'FJI') {
+ if (loc === 'RUS' || loc === 'FJI') {
// Russia and Fiji have landmasses that cross the antimeridian,
// we need to add +360 to their longitude coordinates, so that
// polygon 'contains' doesn't get confused when crossing the antimeridian.
@@ -97,32 +102,29 @@ function feature2polygons(feature) {
// Note that other countries have polygons on either side of the antimeridian
// (e.g. some Aleutian island for the USA), but those don't confuse
// the 'contains' method; these are skipped here.
- appendPolygon = function(_pts) {
+ appendPolygon = function (_pts) {
var pts;
- if(doesCrossAntiMerdian(_pts) === null) {
+ if (doesCrossAntiMerdian(_pts) === null) {
pts = _pts;
} else {
pts = new Array(_pts.length);
- for(m = 0; m < _pts.length; m++) {
+ for (m = 0; m < _pts.length; m++) {
// do not mutate calcdata[i][j].geojson !!
- pts[m] = [
- _pts[m][0] < 0 ? _pts[m][0] + 360 : _pts[m][0],
- _pts[m][1]
- ];
+ pts[m] = [_pts[m][0] < 0 ? _pts[m][0] + 360 : _pts[m][0], _pts[m][1]];
}
}
polygons.push(polygon.tester(pts));
};
- } else if(loc === 'ATA') {
+ } else if (loc === 'ATA') {
// Antarctica has a landmass that wraps around every longitudes which
// confuses the 'contains' methods.
- appendPolygon = function(pts) {
+ appendPolygon = function (pts) {
var crossAntiMeridianIndex = doesCrossAntiMerdian(pts);
// polygon that do not cross anti-meridian need no special handling
- if(crossAntiMeridianIndex === null) {
+ if (crossAntiMeridianIndex === null) {
return polygons.push(polygon.tester(pts));
}
@@ -135,10 +137,10 @@ function feature2polygons(feature) {
var stitch = new Array(pts.length + 1);
var si = 0;
- for(m = 0; m < pts.length; m++) {
- if(m > crossAntiMeridianIndex) {
+ for (m = 0; m < pts.length; m++) {
+ if (m > crossAntiMeridianIndex) {
stitch[si++] = [pts[m][0] + 360, pts[m][1]];
- } else if(m === crossAntiMeridianIndex) {
+ } else if (m === crossAntiMeridianIndex) {
stitch[si++] = pts[m];
stitch[si++] = [pts[m][0], -90];
} else {
@@ -155,21 +157,21 @@ function feature2polygons(feature) {
};
} else {
// otherwise using same array ref is fine
- appendPolygon = function(pts) {
+ appendPolygon = function (pts) {
polygons.push(polygon.tester(pts));
};
}
- switch(geometry.type) {
+ switch (geometry.type) {
case 'MultiPolygon':
- for(j = 0; j < coords.length; j++) {
- for(k = 0; k < coords[j].length; k++) {
+ for (j = 0; j < coords.length; j++) {
+ for (k = 0; k < coords[j].length; k++) {
appendPolygon(coords[j][k]);
}
}
break;
case 'Polygon':
- for(j = 0; j < coords.length; j++) {
+ for (j = 0; j < coords.length; j++) {
appendPolygon(coords[j]);
}
break;
@@ -185,7 +187,7 @@ function getTraceGeojson(trace) {
// This should not happen, but just in case something goes
// really wrong when fetching the GeoJSON
- if(!isPlainObject(geojsonIn)) {
+ if (!isPlainObject(geojsonIn)) {
loggers.error('Oops ... something went wrong when fetching ' + g);
return false;
}
@@ -197,15 +199,15 @@ function extractTraceFeature(calcTrace) {
var trace = calcTrace[0].trace;
var geojsonIn = getTraceGeojson(trace);
- if(!geojsonIn) return false;
+ if (!geojsonIn) return false;
var lookup = {};
var featuresOut = [];
var i;
- for(i = 0; i < trace._length; i++) {
+ for (i = 0; i < trace._length; i++) {
var cdi = calcTrace[i];
- if(cdi.loc || cdi.loc === 0) {
+ if (cdi.loc || cdi.loc === 0) {
lookup[cdi.loc] = cdi;
}
}
@@ -214,10 +216,10 @@ function extractTraceFeature(calcTrace) {
var id = nestedProperty(fIn, trace.featureidkey || 'id').get();
var cdi = lookup[id];
- if(cdi) {
+ if (cdi) {
var geometry = fIn.geometry;
- if(geometry.type === 'Polygon' || geometry.type === 'MultiPolygon') {
+ if (geometry.type === 'Polygon' || geometry.type === 'MultiPolygon') {
var fOut = {
type: 'Feature',
id: id,
@@ -238,11 +240,15 @@ function extractTraceFeature(calcTrace) {
featuresOut.push(fOut);
} else {
- loggers.log([
- 'Location', cdi.loc, 'does not have a valid GeoJSON geometry.',
- 'Traces with locationmode *geojson-id* only support',
- '*Polygon* and *MultiPolygon* geometries.'
- ].join(' '));
+ loggers.log(
+ [
+ 'Location',
+ cdi.loc,
+ 'does not have a valid GeoJSON geometry.',
+ 'Traces with locationmode *geojson-id* only support',
+ '*Polygon* and *MultiPolygon* geometries.'
+ ].join(' ')
+ );
}
}
@@ -251,10 +257,10 @@ function extractTraceFeature(calcTrace) {
delete lookup[id];
}
- switch(geojsonIn.type) {
+ switch (geojsonIn.type) {
case 'FeatureCollection':
var featuresIn = geojsonIn.features;
- for(i = 0; i < featuresIn.length; i++) {
+ for (i = 0; i < featuresIn.length; i++) {
appendFeature(featuresIn[i]);
}
break;
@@ -262,20 +268,25 @@ function extractTraceFeature(calcTrace) {
appendFeature(geojsonIn);
break;
default:
- loggers.warn([
- 'Invalid GeoJSON type', (geojsonIn.type || 'none') + '.',
- 'Traces with locationmode *geojson-id* only support',
- '*FeatureCollection* and *Feature* types.'
- ].join(' '));
+ loggers.warn(
+ [
+ 'Invalid GeoJSON type',
+ (geojsonIn.type || 'none') + '.',
+ 'Traces with locationmode *geojson-id* only support',
+ '*FeatureCollection* and *Feature* types.'
+ ].join(' ')
+ );
return false;
}
- for(var loc in lookup) {
- loggers.log([
- 'Location *' + loc + '*',
- 'does not have a matching feature with id-key',
- '*' + trace.featureidkey + '*.'
- ].join(' '));
+ for (var loc in lookup) {
+ loggers.log(
+ [
+ 'Location *' + loc + '*',
+ 'does not have a matching feature with id-key',
+ '*' + trace.featureidkey + '*.'
+ ].join(' ')
+ );
}
return featuresOut;
@@ -289,14 +300,14 @@ function findCentroid(feature) {
var geometry = feature.geometry;
var poly;
- if(geometry.type === 'MultiPolygon') {
+ if (geometry.type === 'MultiPolygon') {
var coords = geometry.coordinates;
var maxArea = 0;
- for(var i = 0; i < coords.length; i++) {
- var polyi = {type: 'Polygon', coordinates: coords[i]};
+ for (var i = 0; i < coords.length; i++) {
+ var polyi = { type: 'Polygon', coordinates: coords[i] };
var area = turfArea(polyi);
- if(area > maxArea) {
+ if (area > maxArea) {
maxArea = area;
poly = polyi;
}
@@ -313,13 +324,14 @@ function fetchTraceGeoData(calcData) {
var promises = [];
function fetch(url) {
- return new Promise(function(resolve, reject) {
- d3.json(url, function(err, d) {
- if(err) {
+ return new Promise(function (resolve, reject) {
+ d3.json(url, function (err, d) {
+ if (err) {
delete PlotlyGeoAssets[url];
- var msg = err.status === 404 ?
- ('GeoJSON at URL "' + url + '" does not exist.') :
- ('Unexpected error while fetching from ' + url);
+ var msg =
+ err.status === 404
+ ? 'GeoJSON at URL "' + url + '" does not exist.'
+ : 'Unexpected error while fetching from ' + url;
return reject(new Error(msg));
}
@@ -330,14 +342,14 @@ function fetchTraceGeoData(calcData) {
}
function wait(url) {
- return new Promise(function(resolve, reject) {
+ return new Promise(function (resolve, reject) {
var cnt = 0;
- var interval = setInterval(function() {
- if(PlotlyGeoAssets[url] && PlotlyGeoAssets[url] !== 'pending') {
+ var interval = setInterval(function () {
+ if (PlotlyGeoAssets[url] && PlotlyGeoAssets[url] !== 'pending') {
clearInterval(interval);
return resolve(PlotlyGeoAssets[url]);
}
- if(cnt > 100) {
+ if (cnt > 100) {
clearInterval(interval);
return reject('Unexpected error while fetching from ' + url);
}
@@ -346,15 +358,15 @@ function fetchTraceGeoData(calcData) {
});
}
- for(var i = 0; i < calcData.length; i++) {
+ for (var i = 0; i < calcData.length; i++) {
var trace = calcData[i][0].trace;
var url = trace.geojson;
- if(typeof url === 'string') {
- if(!PlotlyGeoAssets[url]) {
+ if (typeof url === 'string') {
+ if (!PlotlyGeoAssets[url]) {
PlotlyGeoAssets[url] = 'pending';
promises.push(fetch(url));
- } else if(PlotlyGeoAssets[url] === 'pending') {
+ } else if (PlotlyGeoAssets[url] === 'pending') {
promises.push(wait(url));
}
}
diff --git a/src/lib/usa_location_names.js b/src/lib/usa_location_names.js
new file mode 100644
index 00000000000..117451364d4
--- /dev/null
+++ b/src/lib/usa_location_names.js
@@ -0,0 +1,65 @@
+'use strict';
+
+// Mapping of lowercase full US state names to two-letter abbreviations
+const usaLocationList = {
+ alabama: 'AL',
+ alaska: 'AK',
+ arizona: 'AZ',
+ arkansas: 'AR',
+ california: 'CA',
+ colorado: 'CO',
+ connecticut: 'CT',
+ delaware: 'DE',
+ 'district of columbia': 'DC',
+ florida: 'FL',
+ georgia: 'GA',
+ hawaii: 'HI',
+ idaho: 'ID',
+ illinois: 'IL',
+ indiana: 'IN',
+ iowa: 'IA',
+ kansas: 'KS',
+ kentucky: 'KY',
+ louisiana: 'LA',
+ maine: 'ME',
+ maryland: 'MD',
+ massachusetts: 'MA',
+ michigan: 'MI',
+ minnesota: 'MN',
+ mississippi: 'MS',
+ missouri: 'MO',
+ montana: 'MT',
+ nebraska: 'NE',
+ nevada: 'NV',
+ 'new hampshire': 'NH',
+ 'new jersey': 'NJ',
+ 'new mexico': 'NM',
+ 'new york': 'NY',
+ 'north carolina': 'NC',
+ 'north dakota': 'ND',
+ ohio: 'OH',
+ oklahoma: 'OK',
+ oregon: 'OR',
+ pennsylvania: 'PA',
+ 'rhode island': 'RI',
+ 'south carolina': 'SC',
+ 'south dakota': 'SD',
+ tennessee: 'TN',
+ texas: 'TX',
+ utah: 'UT',
+ vermont: 'VT',
+ virginia: 'VA',
+ washington: 'WA',
+ 'washington dc': 'DC',
+ 'washington d.c.': 'DC',
+ 'west virginia': 'WV',
+ wisconsin: 'WI',
+ wyoming: 'WY'
+};
+
+const usaLocationAbbreviations = new Set(Object.values(usaLocationList));
+
+module.exports = {
+ usaLocationAbbreviations,
+ usaLocationList
+};
diff --git a/src/traces/scattergeo/attributes.js b/src/traces/scattergeo/attributes.js
index f2fb2639cf8..9059261f671 100644
--- a/src/traces/scattergeo/attributes.js
+++ b/src/traces/scattergeo/attributes.js
@@ -48,7 +48,9 @@ module.exports = overrideAll(
'to regions on the map.',
'Values *ISO-3*, *USA-states*, *country names* correspond to features on',
'the base map and value *geojson-id* corresponds to features from a custom',
- 'GeoJSON linked to the `geojson` attribute.'
+ 'GeoJSON linked to the `geojson` attribute.',
+ '*USA-states* accepts both two-letter abbreviations (e.g. *CA*) and',
+ 'full state names (e.g. *California*).'
].join(' ')
},
diff --git a/test/image/baselines/geo_choropleth-usa.png b/test/image/baselines/geo_choropleth-usa.png
index b4e155406d8..16716b556bf 100644
Binary files a/test/image/baselines/geo_choropleth-usa.png and b/test/image/baselines/geo_choropleth-usa.png differ
diff --git a/test/image/baselines/map_custom-style.png b/test/image/baselines/map_custom-style.png
index 7a79826bc26..6db20064a00 100644
Binary files a/test/image/baselines/map_custom-style.png and b/test/image/baselines/map_custom-style.png differ
diff --git a/test/image/mocks/geo_choropleth-usa.json b/test/image/mocks/geo_choropleth-usa.json
index edad7315c0f..88329cbb828 100644
--- a/test/image/mocks/geo_choropleth-usa.json
+++ b/test/image/mocks/geo_choropleth-usa.json
@@ -2,6 +2,13 @@
"data": [
{
"autocolorscale": false,
+ "colorbar": {
+ "title": { "text": "Millions USD" }
+ },
+ "locationmode": "USA-states",
+ "name": "",
+ "type": "choropleth",
+ "zmin": 13.31,
"zmax": 16472.88,
"colorscale": [
[0, "rgb(242,240,247)"],
@@ -63,7 +70,6 @@
"Wisconsin
--
Beef: 107.3
Pork: 38.6
Poultry: 34.5
Dairy: 633.6
--
Fruits: 133.8
Veggies: 148.99
--
Wheat: 96.7
Corn: 460.5
Cotton: 0.0",
"Wyoming
--
Beef: 75.1
Pork: 33.2
Poultry: 0.1
Dairy: 2.89
--
Fruits: 0.17
Veggies: 10.23
--
Wheat: 20.7
Corn: 9.0
Cotton: 0.0"
],
- "zmin": 13.31,
"locations": [
"AL",
"AK",
@@ -116,10 +122,6 @@
"WI",
"WY"
],
- "colorbar": {
- "title": { "text": "Millions USD" }
- },
- "type": "choropleth",
"z": [
1390.63, 13.31, 1463.17, 3586.02, 16472.88, 1851.33, 259.62, 282.19,
3764.09, 2860.84, 401.84, 2078.89, 8709.48, 5050.23, 11273.76, 4589.01,
@@ -128,8 +130,138 @@
3761.96, 3979.79, 1646.41, 1794.57, 1969.87, 31.59, 929.93, 3770.19,
1535.13, 6648.22, 453.39, 180.14, 1146.48, 3894.81, 138.89, 3090.23,
349.69
+ ]
+ },
+ {
+ "autocolorscale": false,
+ "geo": "geo2",
+ "locationmode": "USA-states",
+ "name": "",
+ "showscale": false,
+ "type": "choropleth",
+ "zmax": 16472.88,
+ "zmin": 13.31,
+ "colorscale": [
+ [0, "rgb(242,240,247)"],
+ [0.2, "rgb(218,218,235)"],
+ [0.4, "rgb(188,189,220)"],
+ [0.6, "rgb(158,154,200)"],
+ [0.8, "rgb(117,107,177)"],
+ [1, "rgb(84,39,143)"]
+ ],
+ "text": [
+ "Alabama
--
Beef: 34.4
Pork: 10.6
Poultry: 481.0
Dairy: 4.06
--
Fruits: 25.11
Veggies: 14.33
--
Wheat: 70.0
Corn: 34.9
Cotton: 317.61",
+ "Alaska
--
Beef: 0.2
Pork: 0.1
Poultry: 0.0
Dairy: 0.19
--
Fruits: 0.0
Veggies: 1.56
--
Wheat: 0.0
Corn: 0.0
Cotton: 0.0",
+ "Arizona
--
Beef: 71.3
Pork: 17.9
Poultry: 0.0
Dairy: 105.48
--
Fruits: 60.27
Veggies: 386.91
--
Wheat: 48.7
Corn: 7.3
Cotton: 423.95",
+ "Arkansas
--
Beef: 53.2
Pork: 29.4
Poultry: 562.9
Dairy: 3.53
--
Fruits: 6.88
Veggies: 11.45
--
Wheat: 114.5
Corn: 69.5
Cotton: 665.44",
+ " California
--
Beef: 228.7
Pork: 11.1
Poultry: 225.4
Dairy: 929.95
--
Fruits: 8736.4
Veggies: 2106.79
--
Wheat: 249.3
Corn: 34.6
Cotton: 1064.95",
+ "Colorado
--
Beef: 261.4
Pork: 66.0
Poultry: 14.0
Dairy: 71.94
--
Fruits: 17.99
Veggies: 118.27
--
Wheat: 400.5
Corn: 183.2
Cotton: 0.0",
+ "Connecticut
--
Beef: 1.1
Pork: 0.1
Poultry: 6.9
Dairy: 9.49
--
Fruits: 13.1
Veggies: 11.16
--
Wheat: 0.0
Corn: 0.0
Cotton: 0.0",
+ "Delaware
--
Beef: 0.4
Pork: 0.6
Poultry: 114.7
Dairy: 2.3
--
Fruits: 1.53
Veggies: 20.03
--
Wheat: 22.9
Corn: 26.9
Cotton: 0.0",
+ "Florida
--
Beef: 42.6
Pork: 0.9
Poultry: 56.9
Dairy: 66.31
--
Fruits: 1371.36
Veggies: 450.86
--
Wheat: 1.8
Corn: 3.5
Cotton: 78.24",
+ "Georgia
--
Beef: 31.0
Pork: 18.9
Poultry: 630.4
Dairy: 38.38
--
Fruits: 233.51
Veggies: 154.77
--
Wheat: 65.4
Corn: 57.8
Cotton: 1154.07",
+ "Hawaii
--
Beef: 4.0
Pork: 0.7
Poultry: 1.3
Dairy: 1.16
--
Fruits: 55.51
Veggies: 24.83
--
Wheat: 0.0
Corn: 0.0
Cotton: 0.0",
+ "Idaho
--
Beef: 119.8
Pork: 0.0
Poultry: 2.4
Dairy: 294.6
--
Fruits: 21.64
Veggies: 319.19
--
Wheat: 568.2
Corn: 24.0
Cotton: 0.0",
+ "Illinois
--
Beef: 53.7
Pork: 394.0
Poultry: 14.0
Dairy: 45.82
--
Fruits: 12.53
Veggies: 39.95
--
Wheat: 223.8
Corn: 2228.5
Cotton: 0.0",
+ "Indiana
--
Beef: 21.9
Pork: 341.9
Poultry: 165.6
Dairy: 89.7
--
Fruits: 12.98
Veggies: 37.89
--
Wheat: 114.0
Corn: 1123.2
Cotton: 0.0",
+ "Iowa
--
Beef: 289.8
Pork: 1895.6
Poultry: 155.6
Dairy: 107.0
--
Fruits: 3.24
Veggies: 7.1
--
Wheat: 3.1
Corn: 2529.8
Cotton: 0.0",
+ "Kansas
--
Beef: 659.3
Pork: 179.4
Poultry: 6.4
Dairy: 65.45
--
Fruits: 3.11
Veggies: 9.32
--
Wheat: 1426.5
Corn: 457.3
Cotton: 43.98",
+ "Kentucky
--
Beef: 54.8
Pork: 34.2
Poultry: 151.3
Dairy: 28.27
--
Fruits: 6.6
Veggies: 0.0
--
Wheat: 149.3
Corn: 179.1
Cotton: 0.0",
+ "Louisiana
--
Beef: 19.8
Pork: 0.8
Poultry: 77.2
Dairy: 6.02
--
Fruits: 17.83
Veggies: 17.25
--
Wheat: 78.7
Corn: 91.4
Cotton: 280.42",
+ "Maine
--
Beef: 1.4
Pork: 0.5
Poultry: 10.4
Dairy: 16.18
--
Fruits: 52.01
Veggies: 62.9
--
Wheat: 0.0
Corn: 0.0
Cotton: 0.0",
+ "Maryland
--
Beef: 5.6
Pork: 3.1
Poultry: 127.0
Dairy: 24.81
--
Fruits: 12.9
Veggies: 20.43
--
Wheat: 55.8
Corn: 54.1
Cotton: 0.0",
+ "Massachusetts
--
Beef: 0.6
Pork: 0.5
Poultry: 0.6
Dairy: 5.81
--
Fruits: 80.83
Veggies: 21.13
--
Wheat: 0.0
Corn: 0.0
Cotton: 0.0",
+ "Michigan
--
Beef: 37.7
Pork: 118.1
Poultry: 32.6
Dairy: 214.82
--
Fruits: 257.69
Veggies: 189.96
--
Wheat: 247.0
Corn: 381.5
Cotton: 0.0",
+ "Minnesota
--
Beef: 112.3
Pork: 740.4
Poultry: 189.2
Dairy: 218.05
--
Fruits: 7.91
Veggies: 120.37
--
Wheat: 538.1
Corn: 1264.3
Cotton: 0.0",
+ "Mississippi
--
Beef: 12.8
Pork: 30.4
Poultry: 370.8
Dairy: 5.45
--
Fruits: 17.04
Veggies: 27.87
--
Wheat: 102.2
Corn: 110.0
Cotton: 494.75",
+ "Missouri
--
Beef: 137.2
Pork: 277.3
Poultry: 196.1
Dairy: 34.26
--
Fruits: 13.18
Veggies: 17.9
--
Wheat: 161.7
Corn: 428.8
Cotton: 345.29",
+ "Montana
--
Beef: 105.0
Pork: 16.7
Poultry: 1.7
Dairy: 6.82
--
Fruits: 3.3
Veggies: 45.27
--
Wheat: 1198.1
Corn: 5.4
Cotton: 0.0",
+ "Nebraska
--
Beef: 762.2
Pork: 262.5
Poultry: 31.4
Dairy: 30.07
--
Fruits: 2.16
Veggies: 53.5
--
Wheat: 292.3
Corn: 1735.9
Cotton: 0.0",
+ "Nevada
--
Beef: 21.8
Pork: 0.2
Poultry: 0.0
Dairy: 16.57
--
Fruits: 1.19
Veggies: 27.93
--
Wheat: 5.4
Corn: 0.0
Cotton: 0.0",
+ "New Hampshire
--
Beef: 0.6
Pork: 0.2
Poultry: 0.8
Dairy: 7.46
--
Fruits: 7.98
Veggies: 4.5
--
Wheat: 0.0
Corn: 0.0
Cotton: 0.0",
+ "New Jersey
--
Beef: 0.8
Pork: 0.4
Poultry: 4.6
Dairy: 3.37
--
Fruits: 109.45
Veggies: 56.54
--
Wheat: 6.7
Corn: 10.1
Cotton: 0.0",
+ "New Mexico
--
Beef: 117.2
Pork: 0.1
Poultry: 0.3
Dairy: 191.01
--
Fruits: 101.9
Veggies: 43.88
--
Wheat: 13.9
Corn: 11.2
Cotton: 72.62",
+ "New York
--
Beef: 22.2
Pork: 5.8
Poultry: 17.7
Dairy: 331.8
--
Fruits: 202.56
Veggies: 143.37
--
Wheat: 29.9
Corn: 106.1
Cotton: 0.0",
+ "North Carolina
--
Beef: 24.8
Pork: 702.8
Poultry: 598.4
Dairy: 24.9
--
Fruits: 74.47
Veggies: 150.45
--
Wheat: 200.3
Corn: 92.2
Cotton: 470.86",
+ "North Dakota
--
Beef: 78.5
Pork: 16.1
Poultry: 0.5
Dairy: 8.14
--
Fruits: 0.25
Veggies: 130.79
--
Wheat: 1664.5
Corn: 236.1
Cotton: 0.0",
+ "Ohio
--
Beef: 36.2
Pork: 199.1
Poultry: 129.9
Dairy: 134.57
--
Fruits: 27.21
Veggies: 53.53
--
Wheat: 207.4
Corn: 535.1
Cotton: 0.0",
+ "Oklahoma
--
Beef: 337.6
Pork: 265.3
Poultry: 131.1
Dairy: 24.35
--
Fruits: 9.24
Veggies: 8.9
--
Wheat: 324.8
Corn: 27.5
Cotton: 110.54",
+ "Oregon
--
Beef: 58.8
Pork: 1.4
Poultry: 14.2
Dairy: 63.66
--
Fruits: 315.04
Veggies: 126.5
--
Wheat: 320.3
Corn: 11.7
Cotton: 0.0",
+ "Pennsylvania
--
Beef: 50.9
Pork: 91.3
Poultry: 169.8
Dairy: 280.87
--
Fruits: 89.48
Veggies: 38.26
--
Wheat: 41.0
Corn: 112.1
Cotton: 0.0",
+ "Rhode Island
--
Beef: 0.1
Pork: 0.1
Poultry: 0.2
Dairy: 0.52
--
Fruits: 2.83
Veggies: 3.02
--
Wheat: 0.0
Corn: 0.0
Cotton: 0.0",
+ "South Carolina
--
Beef: 15.2
Pork: 10.9
Poultry: 186.5
Dairy: 7.62
--
Fruits: 53.45
Veggies: 42.66
--
Wheat: 55.3
Corn: 32.1
Cotton: 206.1",
+ "South Dakota
--
Beef: 193.5
Pork: 160.2
Poultry: 29.3
Dairy: 46.77
--
Fruits: 0.8
Veggies: 4.06
--
Wheat: 704.5
Corn: 643.6
Cotton: 0.0",
+ "Tennessee
--
Beef: 51.1
Pork: 17.6
Poultry: 82.4
Dairy: 21.18
--
Fruits: 6.23
Veggies: 24.67
--
Wheat: 100.0
Corn: 88.8
Cotton: 363.83",
+ "Texas
--
Beef: 961.0
Pork: 42.7
Poultry: 339.2
Dairy: 240.55
--
Fruits: 99.9
Veggies: 115.23
--
Wheat: 309.7
Corn: 167.2
Cotton: 2308.76",
+ "Utah
--
Beef: 27.9
Pork: 59.0
Poultry: 23.1
Dairy: 48.6
--
Fruits: 12.34
Veggies: 6.6
--
Wheat: 42.8
Corn: 5.3
Cotton: 0.0",
+ "Vermont
--
Beef: 6.2
Pork: 0.2
Poultry: 0.9
Dairy: 65.98
--
Fruits: 8.01
Veggies: 4.05
--
Wheat: 0.0
Corn: 0.0
Cotton: 0.0",
+ "Virginia
--
Beef: 39.5
Pork: 16.9
Poultry: 164.7
Dairy: 47.85
--
Fruits: 36.48
Veggies: 27.25
--
Wheat: 77.5
Corn: 39.5
Cotton: 64.84",
+ "Washington
--
Beef: 59.2
Pork: 0.0
Poultry: 35.6
Dairy: 154.18
--
Fruits: 1738.57
Veggies: 363.79
--
Wheat: 786.3
Corn: 29.5
Cotton: 0.0",
+ "West Virginia
--
Beef: 12.0
Pork: 0.3
Poultry: 45.4
Dairy: 3.9
--
Fruits: 11.54
Veggies: 0.0
--
Wheat: 1.6
Corn: 3.5
Cotton: 0.0",
+ "Wisconsin
--
Beef: 107.3
Pork: 38.6
Poultry: 34.5
Dairy: 633.6
--
Fruits: 133.8
Veggies: 148.99
--
Wheat: 96.7
Corn: 460.5
Cotton: 0.0",
+ "Wyoming
--
Beef: 75.1
Pork: 33.2
Poultry: 0.1
Dairy: 2.89
--
Fruits: 0.17
Veggies: 10.23
--
Wheat: 20.7
Corn: 9.0
Cotton: 0.0"
+ ],
+ "locations": [
+ "Alabama",
+ "Alaska",
+ "Arizona",
+ "Arkansas",
+ "California",
+ "Colorado",
+ "Connecticut",
+ "Delaware",
+ "Florida",
+ "Georgia",
+ "Hawaii",
+ "Idaho",
+ "Illinois",
+ "Indiana",
+ "Iowa",
+ "Kansas",
+ "Kentucky",
+ "Louisiana",
+ "Maine",
+ "Maryland",
+ "Massachusetts",
+ "Michigan",
+ "Minnesota",
+ "Mississippi",
+ "Missouri",
+ "Montana",
+ "Nebraska",
+ "Nevada",
+ "New Hampshire",
+ "New Jersey",
+ "New Mexico",
+ "New York",
+ "North Carolina",
+ "North Dakota",
+ "Ohio",
+ "Oklahoma",
+ "Oregon",
+ "Pennsylvania",
+ "Rhode Island",
+ "South Carolina",
+ "South Dakota",
+ "Tennessee",
+ "Texas",
+ "Utah",
+ "Vermont",
+ "Virginia",
+ "Washington",
+ "West Virginia",
+ "Wisconsin",
+ "Wyoming"
],
- "locationmode": "USA-states"
+ "z": [
+ 1390.63, 13.31, 1463.17, 3586.02, 16472.88, 1851.33, 259.62, 282.19,
+ 3764.09, 2860.84, 401.84, 2078.89, 8709.48, 5050.23, 11273.76, 4589.01,
+ 1889.15, 1914.23, 278.37, 692.75, 248.65, 3164.16, 7192.33, 2170.8,
+ 3933.42, 1718, 7114.13, 139.89, 73.06, 500.4, 751.58, 1488.9, 3806.05,
+ 3761.96, 3979.79, 1646.41, 1794.57, 1969.87, 31.59, 929.93, 3770.19,
+ 1535.13, 6648.22, 453.39, 180.14, 1146.48, 3894.81, 138.89, 3090.23,
+ 349.69
+ ]
}
],
"layout": {
@@ -138,7 +270,7 @@
"text": "2011 US Agriculture Exports by State
(Hover for breakdown)"
},
"showlegend": false,
- "height": 598,
+ "height": 1200,
"width": 870,
"geo": {
"showlakes": true,
@@ -146,7 +278,37 @@
"projection": {
"type": "albers usa"
},
- "lakecolor": "rgb(255, 255, 255)"
- }
+ "lakecolor": "rgb(255, 255, 255)",
+ "domain": { "y": [0.55, 1] }
+ },
+ "geo2": {
+ "showlakes": true,
+ "scope": "usa",
+ "projection": {
+ "type": "albers usa"
+ },
+ "lakecolor": "rgb(255, 255, 255)",
+ "domain": { "y": [0, 0.45] }
+ },
+ "annotations": [
+ {
+ "text": "Lookup by two letter location abbreviation",
+ "x": 0.5,
+ "y": 0.53,
+ "xref": "paper",
+ "yref": "paper",
+ "showarrow": false,
+ "font": { "size": 16 }
+ },
+ {
+ "text": "Lookup by full location name",
+ "x": 0.5,
+ "y": -0.02,
+ "xref": "paper",
+ "yref": "paper",
+ "showarrow": false,
+ "font": { "size": 16 }
+ }
+ ]
}
}
diff --git a/test/plot-schema.json b/test/plot-schema.json
index 9e6c6299dad..565942dec36 100644
--- a/test/plot-schema.json
+++ b/test/plot-schema.json
@@ -25447,7 +25447,7 @@
"valType": "number"
},
"locationmode": {
- "description": "The library used by the *country names* `locationmode` option is changing in an upcoming version. Country names in existing plots may not work in the new version. Determines the set of locations used to match entries in `locations` to regions on the map. Values *ISO-3*, *USA-states*, *country names* correspond to features on the base map and value *geojson-id* corresponds to features from a custom GeoJSON linked to the `geojson` attribute.",
+ "description": "The library used by the *country names* `locationmode` option is changing in an upcoming version. Country names in existing plots may not work in the new version. Determines the set of locations used to match entries in `locations` to regions on the map. Values *ISO-3*, *USA-states*, *country names* correspond to features on the base map and value *geojson-id* corresponds to features from a custom GeoJSON linked to the `geojson` attribute. *USA-states* accepts both two-letter abbreviations (e.g. *CA*) and full state names (e.g. *California*).",
"dflt": "ISO-3",
"editType": "calc",
"valType": "enumerated",
@@ -67366,7 +67366,7 @@
}
},
"locationmode": {
- "description": "The library used by the *country names* `locationmode` option is changing in an upcoming version. Country names in existing plots may not work in the new version. Determines the set of locations used to match entries in `locations` to regions on the map. Values *ISO-3*, *USA-states*, *country names* correspond to features on the base map and value *geojson-id* corresponds to features from a custom GeoJSON linked to the `geojson` attribute.",
+ "description": "The library used by the *country names* `locationmode` option is changing in an upcoming version. Country names in existing plots may not work in the new version. Determines the set of locations used to match entries in `locations` to regions on the map. Values *ISO-3*, *USA-states*, *country names* correspond to features on the base map and value *geojson-id* corresponds to features from a custom GeoJSON linked to the `geojson` attribute. *USA-states* accepts both two-letter abbreviations (e.g. *CA*) and full state names (e.g. *California*).",
"dflt": "ISO-3",
"editType": "calc",
"valType": "enumerated",