Thursday, August 25, 2016

Multiple Icons in gvisMaps

The googleVis package is a great way to produce interactive charts. It can be incorporated readily into R Markdown and Shiny apps.

While using the gvisMaps function to visualize locations on the map, I find that there is no argument to easily tweak to plot markers of different colors. This problem can be solved by using the plotGoogleMaps or Leaflet package. However, if for some reason you would like to stick to gvisMaps, below is one solution.

library(googleVis)

If you look at the Google Charts page, you’ll find that it is indeed possible to visualize different markers. Not only can you define the colors, you can also change their styles, simply by having a data column specifying the marker to plot for each entry.

The problem lies in that gvisMaps only takes in the locationvar and tipvar columns of the data. The html ouput of gvisMaps does not include any additional column. The workaround is to manually change this html output.

Select your favorite markers here. For this example, I chose a green and red marker. I did not set the markers to change upon click, but this can be done by choosing a different marker and specifying it under ‘selected’.

iconGreen=paste0("{",
                 "'green': {'normal':'http://icons.iconarchive.com/",
                 "icons/icons-land/vista-map-markers/32/",
                 "Map-Marker-Marker-Outside-Chartreuse-icon.png',",
                 "'selected': 'http://icons.iconarchive.com/",
                 "icons/icons-land/vista-map-markers/32/",
                 "Map-Marker-Marker-Outside-Chartreuse-icon.png'",
                 "},")
iconRed=paste0("'red': {'normal':'http://icons.iconarchive.com/",
                 "icons/icons-land/vista-map-markers/32/",
                 "Map-Marker-Marker-Outside-Pink-icon.png',",
                 "'selected': 'http://icons.iconarchive.com/",
                 "icons/icons-land/vista-map-markers/32/",
                 "Map-Marker-Marker-Outside-Pink-icon.png'",
                 "}}")
icon = paste0(iconGreen,iconRed)

The following function will be used to add the marker column in html.

makejs = function(df){
  jslist = rep(NA, nrow(df))
  for (i in 1:nrow(df)){
    latlong = paste0(df[i,c('Lat','Long')],collapse=',\n')
    tipmark = paste0('"',df[i,c('Tip','marker')],'"',collapse=',\n')
    jslist[i] = paste0('\\[\n ', paste(latlong,tipmark,sep=',\n'), ' \n\\]')
  }
  return(paste(jslist, collapse=',\n'))
}

Prepare the data for plotting.

Andrew$marker = c(rep('green',24), rep('red',23))
head(Andrew)
##         Date/Time UTC  Lat  Long Pressure_mb Speed_kt            Category
## 1 1992-08-16 18:00:00 10.8 -35.5        1010       25 Tropical Depression
## 2 1992-08-17 00:00:00 11.2 -37.4        1009       30 Tropical Depression
## 3 1992-08-17 06:00:00 11.7 -39.6        1008       30 Tropical Depression
## 4 1992-08-17 12:00:00 12.3 -42.0        1006       35      Tropical Storm
## 5 1992-08-17 18:00:00 13.1 -44.2        1003       35      Tropical Storm
## 6 1992-08-18 00:00:00 13.6 -46.2        1002       40      Tropical Storm
##      LatLong                                              Tip marker
## 1 10.8:-35.5 Tropical Depression<BR>Pressure=1010<BR>Speed=25  green
## 2 11.2:-37.4 Tropical Depression<BR>Pressure=1009<BR>Speed=30  green
## 3 11.7:-39.6 Tropical Depression<BR>Pressure=1008<BR>Speed=30  green
## 4   12.3:-42      Tropical Storm<BR>Pressure=1006<BR>Speed=35  green
## 5 13.1:-44.2      Tropical Storm<BR>Pressure=1003<BR>Speed=35  green
## 6 13.6:-46.2      Tropical Storm<BR>Pressure=1002<BR>Speed=40  green

Now for the last part…

map = gvisMap(Andrew, "LatLong" , "Tip", 
                     options=list(showTip=TRUE, 
                                  showLine=TRUE,
                                  icons=icon,
                                  enableScrollWheel=TRUE,
                                  mapType='terrain', 
                                  useMapTypeControl=TRUE))
jsData = map[['html']][['chart']][['jsData']]
jsDataNew = gsub("datajson =.*addColumn\\('number','Latitude'\\);",
                 paste("datajson =\n\\[\n", 
                       makejs(Andrew[,c('Lat','Long','Tip','marker')]),
                       "\n];\ndata\\.addColumn\\('number','Latitude'\\);"),
                 jsData)
jsDataNew = gsub("\ndata\\.addRows\\(datajson\\);",
                 "\ndata\\.addColumn\\('string','marker'\\);
                 \ndata\\.addRows\\(datajson\\);",
                 jsDataNew)
map[['html']][['chart']][['jsData']] = jsDataNew

Now you can visualize the map using plot(map) or use it in Shiny apps etc.

No comments:

Post a Comment