Add Data to Ggvis Tooltip That's Contained in the Input Dataset But Not Directly in the Vis

Add data to ggvis tooltip that's contained in the input dataset but not directly in the vis

Yes, it's possible. Normally the client only sends back the columns of data that are actually in the plot. To get other columns, you should use a key to index into the original data: This is simple reproducible example

library(ggvis)
mtc <- mtcars
mtc$id <- 1:nrow(mtc)

all_values <- function(x) {
if(is.null(x)) return(NULL)
row <- mtc[mtc$id == x$id, ]
paste0(names(row), ": ", format(row), collapse = "<br />")
}

mtc %>% ggvis(x = ~wt, y = ~mpg, key := ~id) %>%
layer_points() %>%
add_tooltip(all_values, "hover")

Tooltip in ggvis for R with layer_paths

I was looking around a bit and realized that since paths are made from information from multiple rows of a dataset, it doesn't make sense to try to use a unique row id for the tooltip like we usually do with key.

Then I saw this very nice ggvis tutorial, and the way forward became clearer to me. You need to base the tooltip on your grouping variable, and then somehow winnow the info from the many rows in that group down to a single value. Among other options, you could do this by pulling out just the first row from the group or by using just the unique value when making your in your tooltip function.

Here's examples of what I mean, using the variable group that you use in group_by to pull out the pertinent info.

First, using head to get just the first row:

values = function(x){
if(is.null(x)) return(NULL)
row = head(gg[gg$group == unique(x$group), ], 1)
paste0("State: ", row$state,"<br />",
"Revenue: ", row$revenue, "<br />")
}

Alternatively, just pull the unique values of the variables you want to display (there is one per state/group). This works OK in your case because you are only displaying two values:

values2 = function(x){
if(is.null(x)) return(NULL)
row = gg[gg$group == unique(x$group), ]
paste0("State: ", unique(row$state),"<br />",
"Revenue: ", unique(row$revenue), "<br />")
}

Now take the key argument out of ggvis and use one of the new tooltip functions. Now the interactive graph appears to work fine.

gg %>%
group_by(group) %>%
ggvis(~long, ~lat) %>%
hide_axis("x") %>%
hide_axis("y")%>%
add_tooltip(values, "hover")%>%
layer_paths(fill= ~revenue)

Rstudio shiny ggvis tooltip on mouse hover

You need to add long as a key currently data$long is null in the anonymous function supplied to add_tooltip:

library(shiny)
library(ggvis)

runApp(list(ui = pageWithSidebar(
div(),
sidebarPanel(
sliderInput("n", "Number of points", min = 1, max = nrow(mtcars),
value = 10, step = 1),
uiOutput("plot_ui")
),
mainPanel(
ggvisOutput("plot"),
tableOutput("mtc_table")
)
)
, server= function(input, output, session) {
# A reactive subset of mtcars
mtc <- reactive({
data = mtcars[1:input$n, ]
data$long = as.character(paste0("A car with ",data$cyl," cylinders and ",data$gear," gears and ",data$carb, " carburators"))
data
})
# A simple visualisation. In shiny apps, need to register observers
# and tell shiny where to put the controls
mtc %>%
ggvis(~wt, ~mpg, key:= ~long) %>%
layer_points(fill = ~factor(long)) %>%
add_tooltip(function(data){
paste0("Wt: ", data$wt, "<br>", "Mpg: ",as.character(data$mpg), "<br>", "String: ", as.character(data$long))
}, "hover") %>%
bind_shiny("plot", "plot_ui")

output$mtc_table <- renderTable({
mtc()[, c("wt", "mpg", "long")]
})
})
)

Sample Image

Display plot data in ggvis tooltip

One option is to subset to only the columns of interest within your tooltip function, and then display all values from this dataset.

my_tooltip <- function(tt) {
if (is.null(tt)) return(NULL)
if (is.null(tt$ID)) return(NULL)

Datapoint <- alldata[alldata$ID == tt$ID, c("Species", "ID", input$x, input$y)]

paste0(names(Datapoint), ": ", format(Datapoint), collapse = "<br />")
}

Or just use, e.g., input$x directly as these are characters so are easy to pull out of datasets and use as tooltip names.

my_tooltip <- function(tt) {
if (is.null(tt)) return(NULL)
if (is.null(tt$ID)) return(NULL)

Datapoint = alldata[alldata$ID == tt$ID, ]

paste0("<b>", "Species: ", Datapoint$`Species`,
"</b><br>", "ID: ", Datapoint$`ID`,
"<br>", input$x, ": ", Datapoint[[input$x]],
"<br>", input$y, ": ", Datapoint[[input$y]])
}

ggvis fill attribute is not working for certain layers or variables

From ?layer_bars

If grouping var is continuous, you need to manually specify grouping

iris %>%  
group_by(Sepal.Length) %>%
ggvis(x= ~Sepal.Length, y = ~Sepal.Width, fill = ~Sepal.Length) %>%
layer_bars()

Which gives:

Sample Image

Create dynamic ggvis chart from uploaded file in shiny

Here is an attempt, I added a couple of reactive blocks to get the names that should be added on the plot axis.

A trick you can use is to create a filtered dataframe that has two columns x and y and that changes when the user changes the values in the selectInput. You can then tell ggvis to plot x and y from that filtered dataframe and the plot will be interactive.

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

shinyServer(function(input, output, session) {
#load the data when the user inputs a file
theData <- reactive({
infile <- input$datfile
if(is.null(infile))
return(NULL)
d <- read.csv(infile$datapath, header = T)
d
})

# dynamic variable names
observe({
data<-theData()
updateSelectInput(session, 'x', choices = names(data))
updateSelectInput(session, 'y', choices = names(data))

}) # end observe

#gets the y variable name, will be used to change the plot legends
yVarName<-reactive({
input$y
})

#gets the x variable name, will be used to change the plot legends
xVarName<-reactive({
input$x
})

#make the filteredData frame

filteredData<-reactive({
data<-isolate(theData())
#if there is no input, make a dummy dataframe
if(input$x=="x" && input$y=="y"){
if(is.null(data)){
data<-data.frame(x=0,y=0)
}
}else{
data<-data[,c(input$x,input$y)]
names(data)<-c("x","y")
}
data
})

#plot the ggvis plot in a reactive block so that it changes with filteredData
vis<-reactive({
plotData<-filteredData()
plotData %>%
ggvis(~x, ~y) %>%
layer_points() %>%
add_axis("y", title = yVarName()) %>%
add_axis("x", title = xVarName()) %>%
add_tooltip(function(df) format(sqrt(df$x),digits=2))
})
vis%>%bind_shiny("plot", "plot_ui")

})

EDIT: added tooltips.



Related Topics



Leave a reply



Submit