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$
  • $\begingroup$ I get a stream of errors when evaluating your code with V10.3 on OS X $\endgroup$ – Mike Honeychurch Nov 14 '15 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 '15 at 23:39
  • $\begingroup$ @MikeHoneychurch I'm running 10.2 on Windows 64 bit, student edition. $\endgroup$ – DavisDude Nov 15 '15 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$ – Sjoerd C. de Vries Nov 21 '15 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$ – Sjoerd C. de Vries Nov 23 '15 at 22:50
5
$\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$
  • $\begingroup$ Nice catch! That had me struggling for so long... $\endgroup$ – DavisDude Apr 29 '16 at 10:20
  • $\begingroup$ Glad I could help, this one was fun! $\endgroup$ – Jason B. Apr 29 '16 at 10:20
  • $\begingroup$ Nice sleuthing, +1 $\endgroup$ – ciao Apr 29 '16 at 10:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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