Play audio by clicking on ggplot/plotly scatter plot - r

I've created a scatter plot with ggplot2 and would like to link the data points with corresponding sound files. In a shiny app it should then be possible to click on or hover over a data point to play the sound file. While I manage to get the plot into a shiny app, I am struggling with the inclusion of tags$audio, as described here, into the plot.
library(shiny)
library(plotly)
ui <- fluidPage(
plotlyOutput('scatter')
)
server <- function(input, output) {
output$scatter <- renderPlotly({
ggplotly(p)
})
}
shinyApp(ui = ui, server = server)
The plotly plot displays a tooltip with the info per data point, among others also the URL for the sound file. See the working example here: https://chart-studio.plotly.com/~petergi/1.
The ggplot2 code contains the URL information in the aes 'text'.
p <- ggplot(without_outliers) +
aes(x = T2, y = T1, label = labels, col = next_label,
text = paste0("URL: ", "https://www.yyyy.zz/audio/", tolower(bundle), ".mp3"))
Any hint to how to bring an audio player to the scatter plot's data points in shiny would be highly appreciated.

In the meantime, I found a working solution in using the R package ggiraph, which enhances ggplot2 with tooltip and onclick functionalities, when used in a shiny application. In a nutshell, a geom_point_interative call can have an onClick argument, which in turn then is a call to a Javascript function to play the audio (without opening a new window or a player).
library(ggplot2)
library(ggiraph)
library(shiny)
p <- ggplot(mtcars, aes(wt, mpg))+
geom_point_interactive(onclick="var audio= new Audio(\"https://file-examples.com/wp-content/uploads/2017/11/file_example_MP3_700KB.mp3\"); audio.play();")
x <- girafe(ggobj = p)
To allow for all different data points in a data frame to be associated with their corresponding audio files, the data frame should be modified to contain a new column with the individual javascript code to play the audio.
An example shiny app can be found here.

Thank you Peter, I managed to get this working with help from your pointers. I know this is a late response but I hope it helps if someone else runs into a similar issue. First, I recommend reviewing the examples shared above.
I managed to get something like this working. However, instead of defining the audio and playing it with the onclick argument, I created a separate javascript file and sourced it through the shiny applet.
I created a separate file called fileNames.js where I defined each variable. Using the example above with only one audio file, this would be: var audio= new Audio("https://file-examples.com/wp-content/uploads/2017/11/file_example_MP3_700KB.mp3");.
In the R shiny applet, I changed the onclick argument in geom_point_interactive() to the javascript code to play the audio file. In your example, the string would be simply audio.play();. For whatever reason passing the multi-line javascript code to the onclick argument didn't work for me.
Early in the ui call, I included includeScript(path = "fileNames.js") to source the javascript into the shiny app.
Here's another helpful example in case someone stumbles upon this thread as I did: https://www.ardata.fr/en/post/2019/05/24/whats-up-ggiraph/

Related

R Shiny API Calls based on reactive input

I am new to R shiny, and Stack Overflow in general. I am trying to create my first dashboard. I have an API call that goes out and collects data from a website called The Blue Alliance. The Blue Alliance is a website that hosts data for high school robotics competitions.
However, in order for the API call to know what event to pull its data from, it needs an event code, which is one of the inputs from a dropdown menu in my UI. How can I make the whole API call reactive so that it subs in the input from the dropdown as part of the URL for the API call?
I have tried placing the reactive() before the #Pull Event Scoring comment by doing something like
reactive(Scores_S4 <- input$Event_Name)
I then tried using it to wrap my entire function, both with and without {} on either side of the parentheses. I have found on various websites they both suggest to and to not use {} when using the reactive function.
server <- function(input, output){
reactive(
#Pull Event live scoring
Scores_S1 <- "https://www.thebluealliance.com/api/v3/event/2022",
Scores_S2 <- input$Event_Name,
Scores_S3 <- "?X-TBA-AUTH-KEY *API Key Goes Here*",
FScores <- paste0(Scores_S1, Scores_S2, Scores_S3),
EScores <- fromJSON(FScores),
EScores <- as.data.frame(EScores)
RPP1 <- ggplot(EScores, aes(reorder(`TeamName`, -`Avg. Hang`), `Avg. Hang`)) + geom_point()
output$RPPP1 <- renderPlot(RPP1))
}
I know that the API call is correct if the value of input$Event_Name is put in, I just need help understanding the reactive portion so that it uses current widget outputs while the app is running. In my understanding, if done correctly, this will allow my ggplot function to create a new graph depending on what is chosen for the input$event. I have a call to "plot output("RPPP1")" in my UI, so this should work once I understand the reactive piece.
Thank you for any and all time put into this, it is all helping a great deal to learn from a community this great.
Something like this might work:
EScores <- reactive({
#Pull Event live scoring
Scores_S1 <- "https://www.thebluealliance.com/api/v3/event/2022"
Scores_S2 <- input$Event_Name
Scores_S3 <- "?X-TBA-AUTH-KEY *API Key Goes Here*"
FScores <- paste0(Scores_S1, Scores_S2, Scores_S3)
EScores <- fromJSON(FScores)
as.data.frame(EScores)
})
output$RPP1 <- renderPlot({
ggplot(EScores(), aes(reorder(`TeamName`, -`Avg. Hang`), `Avg. Hang`)) + geom_point()
output$RPPP1 <- renderPlot(RPP1))
})
But, presumably you'll need something between
FScores <- paste0(Scores_S1, Scores_S2, Scores_S3),
and
EScores <- fromJSON(FScores),
that actually makes a call to the API, like curl() or GET().

Manipulating a user-uploaded file/data in R shiny

I've been working on an R shiny app that is supposed to take a user-uploaded .csv file, do a bunch of manipulations/calculations to that data, and then spit out some graphs. I am completely new to shiny, however, and am very lost. I've tried to look this up, but most results I found take the data and directly show it in a graph. So far I've tried this (code is taken from here):
UI:
ui <- fluidPage(
fileInput("userfile", "Choose CSV File", multiple = TRUE,
accept=c("text/csv","text/comma-separated-values,text/plain",".csv")),
# etc.
Server:
server <- function(input,output){
df <- read.csv(input$userfile$datapath)
# some manipulation, such as adding a new column, for example:
df$timestwo <- 2 * df$column1
}
Is df in the Server code supposed to be the dataframe that was read in from the user-uploaded file? If not, how can I create a dataframe that is able to go through several changes, before making a graph? When I try to run my code I get "Operation not allowed without an active reactive context. (You tried to do something that can only be done from inside a reactive expression or observer." Thanks!
Edit to add: all the data manipulation I wanted to do worked with my sample dataset, but not the user-input one I tried out (which was the exact same data).

display of mapview object in shiny

I’m trying to have two spatial plots side-by-side in shiny, and I was suggested a powerful function, sync of mapview. sync allows to have multiple maps for comparison, a great feature, but unable to figure out integrating or calling its output in shiny. I have gone through ‘mapview for shiny’ and other related links mapview/shiny. The former suggested using renderMapview and mapviewOutput, however it did not work, i.e., no map being displayed. Please see the reproducible code. Also, I tried using #map slot of mapview object in renderLeaflet and calling it via leafletOutput - did not work. In both cases, a shiny window pops up and does not display anything. However, do see the following message in the command window: Warning in spCheckObject(x) : Columns CCN_1 in attribute table contain only NA values and are dropped. - it is related to the data base and confirms that mapview command is being executed but does not provide any leads on absence of plots. Greatly appreciate suggestions or clues on displaying mapview geneated plots in shiny.
library(shiny)
library(mapview)
ui <- fluidPage(
mapviewOutput("samplemap"),
p()
)
server <- function(input, output, session) {
output$samplemap <- renderMapview({
mapview(gadmCHE)
})
}
shinyApp(ui, server)

Export the graph generated by rCharts in shiny application

I want to be able to export the charts generated in my shiny application using rCharts to Image and PDF formats. Is there any provision in the rCharts library for that?
I have earlier used ggvis, It gives an option for resizing the chart in the browser and also an option to download the chart in HTML or PNG format. Anything similar to that?
Edit 1:
I'm using nvd3 and polyCharts as my charting libraries currently.
To download as image or pdf you can use a$exporting(enabled = T), assuming your chart is called a.
library(rCharts)
a <- hPlot(Pulse ~ Height, data = MASS::survey, type = "scatter", group = "Exer")
a$exporting(enabled = T)
a
To follow up on my comment above, I was a bit too quick to respond, as the htmlwidget::saveWidget() function is meant for widgets developed under the htmlwidgets.org framework. However, rCharts has a similar function:
library(rCharts)
a <- nPlot(Pulse ~ Height, data = MASS::survey, type = "scatterChart", group = "Exer")
a$save("demo.html", standalone=TRUE)
Where 'demo.html' is standalone html file. Creating a png is as simple as taking a screenshot. Note that you can also call this function in a shiny app.

Is it possible to download googleVis plots from R?

Follow up from :
https://groups.google.com/forum/#!topic/shiny-discuss/u7gwXc8_vyY
I have the exact same R Shiny structured program as the user in the post, except I am using the googleVis Shiny package for my plots. For example, here is a plot of a gVis table:
output$gvisTable <- renderGvis( {
if (is.null(dataset))
return(NULL)
gvisTable(dataset)
})
EDIT:
My code to save ggplots:
server.R
name <- paste0(input$filename, ".png")
print(p)
if(input$savePlot) {
ggsave(name, p, type="cairo-png")
}
ui.R (in sidePanel)
wellPanel(
textInput('filename', "Filename"),
checkboxInput('savePlot', "Check to save")
)
This is what I am using to try to save gVis plots:
name <- paste0(input$filename, ".png")
if(input$savePlot) {
png(name, *INPUT GVIS PLOT HERE*, type="cairo-png")
dev.off()
}
This does not work: I get the error: 'non-numeric argument to binary operator'
I can't find a way to allow the user to download a gVis plot. I can't use the method in the linked post because you cannot 'print' a gVis plot.
Also, the files are locally saved to my R working directory, but I plan to upload this app to the web. Where would the files be saved for the user? Ideas?
I see no png method documented for gvis objects.
There are two ways to "print" documented in the help page linked from the googleVis main Index page for print.gvis. The default method (when the tag is NULL or "html") is to send a Java script page to your browser. The other (when you set tag="chart" is to construct an html file with the name you give it. I suppose you could arrange something with system commands sent to a running instance of a particular browser, but for that you should use different SO tags so that you attract the interest of people using the same software as you. (I'm using a Mac with Firefox and having no difficulties seeing the "printed" output.) If you plan to "upload it to the web", then you need to have a server. Is my impression this is a bit new for you correct?
print(GTM, tag="chart", file="test.html")
#created in my working directory

Resources