9
$\begingroup$

Bug introduced in 10.0 and persisting through 10.3 or later

Bug behavior is version dependent


When I'm plotting data with GeoRegionValuePlot, I'm getting some strange coloring errors: error

The grid included shows the top 10 countries with arable land per population. However, Australia is colored the as if it were one of the least arable.

I thought it may be due to units, so I tried messing around with TargetUnits to no luck.

I figure that it's due to the fact that the data is being stored as exponents (i.e., the US's arable land/population is 4.81068*10^-3, so that's why it would be colored as if it were higher), but when I made all data have the same exponent, that didn't change anything either.

Any ideas?

Code, for reference:

(* Utility functions *)
removeMissingData[ data_ ] := DeleteCases[ data, _?( ! FreeQ[ #, _Missing ] & ) ]

divideStatsData[ data1_, data2_ ] := ( Module[ { data }, (* Module makes declared variables local *)
   data = { #, CountryData[ #, data1 ], CountryData[ #, data2 ] } & /@ 
     CountryData[];
   (* Missing data / missing data = 1 *)
   data = removeMissingData[ data ];
   { #[[1]], #[[2]] / #[[3]] } & /@ data
   ] 
  )

extractData[ data_ ] := QuantityMagnitude @ Flatten[ Transpose[ data ][[ 2 ]] ]

drawMapWithTooltips[ data_ ] := ( Module[ { rawData, min, max },
   rawData = extractData[ data ];
   { min, max } = { Min[ rawData ], Max[ rawData ] };
   GeoRegionValuePlot[ 
    data,  
    PlotRange -> { min, max },
    GeoLabels -> ( 
      Tooltip[ 
        #1, (* Location *)
        Extract[ 
         Extract[  (* First extract removes ugly braces, second actually gets information *)
          data, 
          Position[ data, #2, 2 ] + { { 0, 1 } } (* Search through table by country (#2) *)
          ], 1 ]
        ] &
      )
    ]
   ] 
  )

sortFromGreatestToLeast[ data_ ] := Sort[ data, #1[[2]] > #2[[2]] &]

(* Data *)    
arableLandPerPopulation = divideStatsData[ "ArableLandArea", "Population" ];
drawMapWithTooltips[ arableLandPerPopulation ]
greatestToLeast = sortFromGreatestToLeast[ arableLandPerPopulation ];
Grid[ Take[ greatestToLeast, 10 ], Frame -> All ]
Grid[ Take[ Reverse[ greatestToLeast ], 10 ], Frame -> All ]

Or if you don't want to load all that data:

arableLandPerPopulation = {{Entity["Country", "Australia"], 
  Quantity[0.0200457, ("Kilometers")^2/("People")]}, {Entity[
   "Country", "Kazakhstan"], 
  Quantity[0.0136973, ("Kilometers")^2/("People")]}, {Entity[
   "Country", "Canada"], 
  Quantity[0.0130036, ("Kilometers")^2/("People")]}, {Entity[
   "Country", "Argentina"], 
  Quantity[0.00939364, ("Kilometers")^2/("People")]}, {Entity[
   "Country", "Niger"], 
  Quantity[0.00890364, ("Kilometers")^2/("People")]}, {Entity[
   "Country", "Russia"], 
  Quantity[0.00840941, ("Kilometers")^2/("People")]}, {Entity[
   "Country", "Ukraine"], 
  Quantity[0.00731436, ("Kilometers")^2/("People")]}, {Entity[
   "Country", "Lithuania"], 
  Quantity[0.00692383, ("Kilometers")^2/("People")]}, {Entity[
   "Country", "Paraguay"], 
  Quantity[0.00637857, ("Kilometers")^2/("People")]}, {Entity[
   "Country", "Niue"], 
  Quantity[0.00620732, ("Kilometers")^2/("People")]}, {Entity[
   "Country", "Belarus"], 
  Quantity[0.0058311, ("Kilometers")^2/("People")]}, {Entity[
   "Country", "Guyana"], 
  Quantity[0.00551926, ("Kilometers")^2/("People")]}, {Entity[
   "Country", "Latvia"], 
  Quantity[0.0053108, ("Kilometers")^2/("People")]}, {Entity[
   "Country", "Moldova"], 
  Quantity[0.00522219, ("Kilometers")^2/("People")]}, {Entity[
   "Country", "SaintHelena"], 
  Quantity[0.00521512, ("Kilometers")^2/("People")]}, {Entity[
   "Country", "Uruguay"], 
  Quantity[0.00514164, ("Kilometers")^2/("People")]}, {Entity[
   "Country", "UnitedStates"], 
  Quantity[0.00481068, ("Kilometers")^2/("People")]}, {Entity[
   "Country", "Estonia"], 
  Quantity[0.00464188, ("Kilometers")^2/("People")]}, {Entity[
   "Country", "Serbia"], 
  Quantity[0.00458116, ("Kilometers")^2/("People")]}};
greatestToLeast = arableLandPerPopulation;

extractData[ data_ ] := QuantityMagnitude @ Flatten[ Transpose[ data ][[ 2 ]] ]
drawMapWithTooltips[ data_ ] := ( Module[ { rawData, min, max },
   rawData = extractData[ data ];
   { min, max } = { Min[ rawData ], Max[ rawData ] };
   GeoRegionValuePlot[ 
    data,  
    PlotRange -> { min, max },
    GeoLabels -> ( 
      Tooltip[ 
        #1, (* Location *)
        Extract[ 
         Extract[  (* First extract removes ugly braces, second actually gets information *)
          data, 
          Position[ data, #2, 2 ] + { { 0, 1 } } (* Search through table by country (#2) *)
          ], 1 ]
        ] &
      )
    ]
   ] 
  )

drawMapWithTooltips[ arableLandPerPopulation ]
greatestToLeast = sortFromGreatestToLeast[ arableLandPerPopulation ];
Grid[ Take[ greatestToLeast, 10 ], Frame -> All ]
Grid[ Take[ Reverse[ greatestToLeast ], 10 ], Frame -> All ]
$\endgroup$
6
  • $\begingroup$ I get a stream of errors when evaluating your code with V10.3 on OS X $\endgroup$ Nov 14, 2015 at 23:37
  • $\begingroup$ Weird. I think I'm running the most up-to-date. It's a student version, I don't know if that would affect anything... $\endgroup$
    – DavisDude
    Nov 14, 2015 at 23:39
  • $\begingroup$ @MikeHoneychurch I'm running 10.2 on Windows 64 bit, student edition. $\endgroup$
    – DavisDude
    Nov 15, 2015 at 0:31
  • 3
    $\begingroup$ This looks like a bug, with PlotRange as one of the preconditions for this behavior. Change PlotRange -> {min, max}, to PlotRange -> All, and it all works. $\endgroup$ Nov 21, 2015 at 19:26
  • 1
    $\begingroup$ 10.0 and 10.1 generate error messages and 10.2 and 10.3 execute error-message free but show the reported erroneous behavior. $\endgroup$ Nov 23, 2015 at 22:50

1 Answer 1

6
$\begingroup$

Not a bug - it's a feature!!

First let's import the data in as quick a fashion as possible,

arableLandPerPopulation=<<"https://gist.githubusercontent.com/jasondbiggs/9e915145a2d4cfa34119fa4d0e535ed2/raw/75387a17c21ee7ff9d7f21e528ca2f971e24209b/gistfile1.txt";

Now look at the GeoRegionValuePlot with and without the PlotRange specified

GeoRegionValuePlot[arableLandPerPopulation, 
   PlotRange -> #] & /@ {Automatic, {0, 0.02}}

enter image description here

Notice the odd coloring in the second plot, that doesn't match the data? You can reproduce that coloring exactly by just ordering the countries alphabetically:

countrylist = arableLandPerPopulation[[All, 1]];
GeoRegionValuePlot[Thread[countrylist -> Range@Length@countrylist]]

Mathematica graphics

So apparently when you give GeoRegionValuePlot a PlotRange it doesn't like, it will default to coloring the countries in alphabetical order. This is in 10.4 - in 10.0 they countries are all colored with the lowest value. Now why didn't it like the specified PlotRange? Because the data given had units!

InputForm[arableLandPerPopulation[[1]]]
(* {Entity["Country", "Afghanistan"], Quantity[0.00218678, "Kilometers"^2/"People"]} *)

If we specify the PlotRange using units, then the problem disappears,

GeoRegionValuePlot[arableLandPerPopulation, 
 PlotRange -> Quantity[{0, .02}, "Kilometers"^2/"People"]]

Mathematica graphics

Okay, you can say it's a bug because it doesn't spit out an error message when the plotted units are Quantity objects and the PlotRange are just numbers, but this is explainable behavior.

Edit - Still a bug!!!

Try to set the upper range of the PlotRange to anything but the max, and it has no effect

GeoRegionValuePlot[arableLandPerPopulation, 
 PlotRange -> Quantity[{0, .001}, "Kilometers"^2/"People"]]

Mathematica graphics

$\endgroup$
3
  • $\begingroup$ Nice catch! That had me struggling for so long... $\endgroup$
    – DavisDude
    Apr 29, 2016 at 10:20
  • $\begingroup$ Glad I could help, this one was fun! $\endgroup$
    – Jason B.
    Apr 29, 2016 at 10:20
  • $\begingroup$ Nice sleuthing, +1 $\endgroup$
    – ciao
    Apr 29, 2016 at 10:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.