Search code examples
rtooltipshinydplyrggvis

ggvis Map & Tooltips


I am trying to layer on tooltips to a map of the US, but wherever I hover... it displays the same data. In addition, the data is wrong. I'm thinking that it is passing through the factor values and not the character value. I tried taking tips from the movie explorer example - http://shiny.rstudio.com/gallery/movie-explorer.html - but, it's not working as I hoped. Any hints or clues I should look into?

Update: I've determined that you can only pass through arguments that are being called into the ggvis function. So, if my tooltip function included region, long, & lat, all of them would appear in the tooltip. Since Population and Income do not appear anywhere in the function, it is not passing them through. I'm still lost on how to proceed, but any ideas would be awesome! :)

library(ggplot2)
library(shiny)
library(ggvis)
library(dplyr)

shinyApp(

  ui = fluidPage(
    #numericInput("n", "n", 1),
    ggvisOutput("map")
  ),

  server = function(input, output) {

    statesData <- reactive({

      states <- data.frame(state.x77)
      states$region <- row.names(state.x77) %>% tolower
      row.names(states) <- NULL

      all_states <- map_data("state") %>%
        mutate(region = tolower(region)) %>%
        left_join(states)

      all_states_unique <- all_states %>%
        select(region, Population, Income, Illiteracy, Life.Exp, Murder, HS.Grad, Frost, Area) %>%
        unique

      states_tooltip <- function(x) {
        if (is.null(x)) return(NULL)
        if (is.null(x$region)) return(NULL)

        # Pick out the movie with this ID
        allStates <- isolate(all_states_unique)
        state <- allStates[allStates$region == x$region, ]

        paste0("<b>", state$region, "</b><br>",
               state$Population, "<br>",
               state$Income

        )
      }

      all_states %>%
        arrange(group, order) %>%
        ggvis(x = ~long, y = ~lat) %>%
        layer_paths(fill = ~region, stroke := .2) %>%
        add_tooltip(states_tooltip, "hover")

    })

    statesData %>% bind_shiny('map')    

  }

)

Solution

  • Add an index to the dataframe you want to pull the tooltip data from:

     state$id <- 1:nrow(state)
    

    ggvis takes a "key" argument to facilitate this kind of tooltip:

     ggvis(x = ~long, y = ~lat, key := ~id) %>%
    

    I tried figuring out that movie example and didn't find it very helpful. This always works for me:

     add_tooltip(function(x) {
                 row <- state[state$id == x$key,]
                 paste0("<b>", row[,"region"], "</b><br>",
                        row[,"Population"], "<br>",
                        row[,"Income"]
                        )})
    

    As for the issue w/ the tooltip always coming up the same, I don't know for sure but think it's due to the order of your layers in the ggvis command. Had a similar problem where I had some polygons layered on top of a scatterplot. It kept trying to draw the tooltip for the polygons (which covered the whole chart) when what I wanted was the individual points to display the tooltip. By reversing their order in the ggvis command (ie layer_points() %>% layer_shapes()) I got it to work.