ramnathv / rMaps

Interactive Maps from R
http://rmaps.github.io
389 stars 194 forks source link

Custom map, ichoropleth and animate #60

Open ekstroem opened 10 years ago

ekstroem commented 10 years ago

Hi,

I've been trying to produce an animated choropleth with a custom map of Denmark but I encounter the following problem: The slider just has a single value, 2000, corresponding to the default minimum and maximum from the template. If I manually edit the resulting html and set the minimum and the maximum for the slider to the correct values then everything works fine. Somehow the range of years is not parsed correctly from my dataset to the html file.

The code looks like this:

d1 <- ichoropleth(life ~ name, ncut=8, data = newdata, animate='year', map='states')
d1$set(
       geographyConfig = list( dataUrl = "/home/claus/sandbox/dk_kom.json" ),
       scope = 'states',
       setProjection = '#! function( element, options ) {
           var projection, path;
           projection = d3.geo.mercator()
           .center([10, 56]).scale(element.offsetWidth*9)
           .translate([element.offsetWidth / 2, element.offsetHeight / 2]);
           path = d3.geo.path().projection( projection );
           return {path: path, projection: projection};
       } !#'
)

d1$save("tstclaus.html", cdn = TRUE)

and the data frame looks like this

> head(newdata, 20)
        kommune life extra year     KOMNAVN        name
69     Aabenraa 79.1    69 2001    Aabenraa    Aabenraa
168    Aabenraa 79.3    69 2002    Aabenraa    Aabenraa
267    Aabenraa 80.3    69 2003    Aabenraa    Aabenraa
366    Aabenraa 80.3    69 2004    Aabenraa    Aabenraa
99      Aalborg 79.8    99 2001     Aalborg     Aalborg
198     Aalborg 80.2    99 2002     Aalborg     Aalborg
297     Aalborg  0.0    99 2003     Aalborg     Aalborg
396     Aalborg 80.2    99 2004     Aalborg     Aalborg
80       Aarhus 79.0    80 2001      Aarhus      Aarhus
179      Aarhus 79.0    80 2002      Aarhus      Aarhus
278      Aarhus 79.1    80 2003      Aarhus      Aarhus
377      Aarhus 80.0    80 2004      Aarhus      Aarhus
57          Ærø 79.9    57 2001         Ærø         Ærø
156         Ærø 78.9    57 2002         Ærø         Ærø
255         Ærø 78.1    57 2003         Ærø         Ærø
354         Ærø 80.4    57 2004         Ærø         Ærø
5   Albertslund 79.4     5 2001 Albertslund Albertslund
104 Albertslund 77.9     5 2002 Albertslund Albertslund
203 Albertslund 80.2     5 2003 Albertslund Albertslund
302 Albertslund 78.9     5 2004 Albertslund Albertslund

year is an integer in the newdata data frame.

Any clues what is wrong? If I run the example with the violent_crimes data the slider works fine - even if I try to map it to the Danish map.

Cheers,

Claus

Oh and yes: have just updates rCharts (dev version) and rMaps.

ekstroem commented 10 years ago

I have tried to track this down further. It turns out, that if I source the code directly the resulting html is fine and the animation slider works.

If I hit the knitr button in the latest version of RStudio I loose the slider range, and the same happens if I use knit2html. Is there a knitr options that might need to be set?

ramnathv commented 10 years ago

Just to make sure I understand, the standalone code snippet works, but when you place it in an Rmd file and knit it, it doesn't. If this were the case, I think I know what might be happening. Since the code is setup to read an external json file, it will only work if you opened the html file on a local server. When you execute the code in RStudio, it shows up in the HTML viewer window, which is a local server. However, when you knit the document, it opens up a preview HTML window, which only displays it as a static HTML file.

If you share your Rmd file with me, I can verify that this indeed is the case, and suggest what can be done to make it work.

ekstroem commented 10 years ago

That is correct. Inside Rmd it does not work, but outside it does. However if I look at the html file generated by knitr in firefox/chrome then it is still static and the html code has a slider range with the same minimum and maximum.

The code is

library(rMaps)

options(rcharts.cdn = TRUE)

options(RCHART_WIDTH = 700, RCHART_HEIGHT = 700)

indata <- read.table(url("http://www.biostatistics.dk/inputdat.txt"), as.is=TRUE)

#          geographyConfig = list( dataUrl = "/Users/cld189/R/dkmap/dk_kom.json" ),

d1 <- ichoropleth(life ~ name, ncuts=5, data = indata, map='states', animate="year")
d1$set(
       geographyConfig = list( dataUrl = "http://www.biostatistics.dk/dk_kom.json" ),
       scope = 'states',
       setProjection = '#! function( element, options ) {
           var projection, path;
           projection = d3.geo.mercator()
           .center([10, 56]).scale(element.offsetWidth*9)
           .translate([element.offsetWidth / 2, element.offsetHeight / 2]);

           path = d3.geo.path().projection( projection );
           return {path: path, projection: projection};
       } !#'
)

d1$save("index.html", cdn=TRUE)

For some reason I cannot get it to render then map when I reference the JSON as an url in dataUrl above, but when I use dataUrl to point to the same file located locally on the computer it works fine. That, however, was not the primary issue

ramnathv commented 10 years ago

The reason why the map does not render when you use a http url is due to browser security restrictions that prevent cross site loading of resources. As for the other issue, I checked it out and you are right in that when knitting inside an Rmd file, the slider min and max are for some reason both set to 2010. It beats me why this happens, but I am sure it is a trivial error at my end.

I will keep digging and suggest a fix as and when I find it.

ekstroem commented 10 years ago

Thank you for looking into this.

Do you want me to keep the issue open until the slider is fixed (as a to-do-list) or do you want me to close it?

Cheers,

Claus

laldew commented 8 years ago

I'm trying to repeat this process. When I use your link to your json, it will work, but when I download that json or try to use my own, nothing will display but the slider. Is there some setting I'm missing?

ekstroem commented 8 years ago

How do you specify the link to the local file when you download it?

When you try your own map do you set

.center([10, 56]).scale(element.offsetWidth*9)

so that it matches your map

laldew commented 8 years ago

I just do geographyConfig = list( dataUrl = "C:/Users/User/Downloads/file.json" ).

No I actually haven't set that. Sorry, I know nothing about JS, so that whole part of this process is completely foreign to me. I also have no experience manipulating .json files in R, so I'm not sure what that line actually represents and how to find that information. 10, 56 looks a lot like it could be a center coordinate for Denmark though, so I'll give that a try while I wait for a response. However, it still isn't working when I download your json, so I think that my main problem is how the file is being called.

laldew commented 8 years ago

I signed up with dropbox and put my topojson file on there so that I could call it from a URL. When I do that, the fill key actually shows up at the bottom of the screen, which is good, but the map is still not displaying. I have set the map to .center([-81, 28]).scale(element.offsetWidth), but I still cannot get the map to display.
Could someone try to run it for me? The link to the topojson is: https://www.dropbox.com/s/iz01zzp9pg25cwq/floridanext.json?dl=0

ekstroem commented 8 years ago

I get the same as you. The legend can be seen but no map. Here's the code I run

library(rMaps)
options(rcharts.cdn = TRUE)
options(RCHART_WIDTH = 700, RCHART_HEIGHT = 700)
indata <- read.table(url("http://www.biostatistics.dk/inputdat.txt"), as.is=TRUE)

d1 <- ichoropleth(life ~ name, ncuts=5, data = indata, map='states', animate="year")
d1$set(
  geographyConfig = list( dataUrl = "/Users/cld189/floridanext.json" ),
  scope = 'states',
  setProjection = '#! function( element, options ) {
  var projection, path;
  projection = d3.geo.mercator()
  .center([-81, 28]).scale(element.offsetWidth*9)
  .translate([element.offsetWidth / 2, element.offsetHeight / 2]);

  path = d3.geo.path().projection( projection );
  return {path: path, projection: projection};
  } !#'
)

d1$save("index.html", cdn=TRUE)
laldew commented 8 years ago

Thanks for trying. It must be a problem with the topojson itself then. The way I created it was through Mapshaper, so it could be doing something strange in the way it creates it. I used the jsonlite package to breakdown and structure my file exactly like your Denmark one, but I couldn't figure out how to export it back into topojson from R.