I am new to Shiny and am trying to add a chord diagram to a shiny server. When I hit the runApp button in RStudio I get the application to run and it generates the UI, but then closes down immediately and I get the following error in the RConsole window: Error in (structure(function (input, output) :
could not find function "renderplot".
Unfortunately, I cannot attach the data as it is proprietary, but I am just creating an adjacency matrix in order to generate the chord plot. The Chord plot works fine outside Shiny. Thanks in advance!
My UI and Server code is below:
library(shiny)
# Starting line
shinyUI(fluidPage(
# Application title
titlePanel("Chord Chart"),
# Sidebar
sidebarLayout(
sidebarPanel(
#Data selection for Chord Chart
selectInput("data","Select a Dataset:",
c("Marine"))),
#The plot created in server.R is displayed
mainPanel(
plotOutput("plot")
)))
)
library(circlize)
library(dplyr)
library(reshape2)
library(manipulate)
library(shiny)
# read marine summaries
marine <- readfile("C:/Personal/R/MarineDataSummary.csv")
# group and summarize by O-D
marine.sum <- marine %>%group_by(Handling_Port, OD_Port_Country) %>%
summarise(tons <-sum(tonnes)) # prepare pivot table
marine.sum1 <- acast(marine.sum, Handling_Port~OD_Port_Country, value.tons="z") # reshape matrix
marine.sum1[is.na(marine.sum1)] <- 0 # set NA to zero
#initialization of server.R
shinyServer(function(input, output) {
output$plot <- renderplot({
c <- chordDiagram(marine.sum1,annotationTrack="grid",preAllocateTracks=list(track.height = 0.3))
##change axis
c <- c + circos.trackPlotRegion(track.index=1, panel.fun=function(x,y) {
xlim = get.cell.meta.data("xlim")
ylim = get.cell.meta.data("ylim")
sector.name=get.cell.meta.data("sector.index")
circos.text(mean(xlim), ylim[1], sector.name,facing="clockwise",
niceFacing=TRUE,adj=c(0,0.4), cex = 0.4)},bg.border=NA)
print(c)
})
})
Related
I created a simple plot that when the user clicks on a point it generates another plot on a second tab, Page_2 -- is it possible to add some custom JS so that when the user clicks on the point they are automatically re-routed to the Page_2 tab?
library(shiny)
library(plotly)
library(tidyverse)
# ui with two panes
# when you click on the outlier in the first plot
# you are routed to the second "point explorer" page
ui <- navbarPage("Plotly On Click Switch Pane",
tabPanel("Page_1",
mainPanel(plotlyOutput("plot"),
tableOutput("text"))),
tabPanel("Page_2",
mainPanel(plotlyOutput("ind_plot"))
))
server <- function(input, output) {
# plot on first page
output$plot <- renderPlotly({
ggplotly(source = "sub_iris",
ggplot(iris, aes(x = Species, y = Petal.Width)) +
geom_boxplot()
)
})
# create reactive for subset plot on second tab
s <- reactive({ event_data("plotly_click", source = "sub_iris") })
# plot text on first page (test)
output$text <- renderTable(event_data("plotly_click", source = "sub_iris"))
# this is the correct plot, but I want to re-route the user here when they click on a point
output$ind_plot <- renderPlotly({
iris_ind <- subset(iris)[subset(s(), curveNumber == 0)$pointNumber + 1,]
ggplotly(
ggplot(iris_ind, aes(x = Species, y = Sepal.Length)) +
geom_bar(stat = "identity")
)
})
}
# Run the application
shinyApp(ui = ui, server = server)
You can use updateNavbarPage after providing your navbarPage with an id:
library(shiny)
library(plotly)
library(tidyverse)
# ui with two panes
# when you click on the outlier in the first plot
# you are routed to the second "point explorer" page
ui <- navbarPage("Plotly On Click Switch Pane", id = "navbarID",
tabPanel("Page_1",
mainPanel(plotlyOutput("plot"),
tableOutput("text"))),
tabPanel("Page_2",
mainPanel(plotlyOutput("ind_plot"))
))
server <- function(input, output, session) {
# plot on first page
output$plot <- renderPlotly({
ggplotly(source = "sub_iris",
ggplot(iris, aes(x = Species, y = Petal.Width)) +
geom_boxplot()
)
})
# create reactive for subset plot on second tab
s <- reactive({
event_data("plotly_click", source = "sub_iris")
})
observeEvent(s(), {
updateNavbarPage(session, inputId = "navbarID", selected = "Page_2")
})
# plot text on first page (test)
output$text <- renderTable(req(s()))
# this is the correct plot, but I want to re-route the user here when they click on a point
output$ind_plot <- renderPlotly({
req(s())
iris_ind <- subset(iris)[subset(s(), curveNumber == 0)$pointNumber + 1,]
ggplotly(
ggplot(iris_ind, aes(x = Species, y = Sepal.Length)) +
geom_bar(stat = "identity")
)
})
}
# Run the application
shinyApp(ui = ui, server = server)
Apparently my code looks fine to me, i have already run one such example, but these onclick() functions are not performing their job no matter what. Can anybody please help me out with that?
Its just a simple code with 6 buttons. 3 buttons for plotting scatter plot, histogram and bar plot whereas one button to hide the output div one button to show output div and one button to change the background of output div.. these onclick functions are not working :/
library(shiny)
library(shinyjs)
library(shinyWidgets)
moduleTestUI <- function(id){
ns=NS(id)
# Application title
titlePanel("My First Shiny Program")
# Sidebar with a slider input for number of bins
sidebarLayout(
sidebarPanel(
tags$style(type='text/css'
, ".btn {padding: 8px; font-size: 120%;background-color: rgb(0, 102, 204);color: white;}"
,"div.main{width: 750px;height: 550px;border-style: double;border-width: 10px;border-color:grey; }"
),
tags$div(id=ns("div1"),
hr(),
actionButton("btn",id=ns("button1"),label = "Scatter Plot"),
actionButton("btn",id=ns("button2"),label = "Histogram"),
actionButton("btn",id=ns("button3"),label = "Bar Plot"),
hr(),
br(),
actionButton("btn",id=ns("button4"),label = "Hide Output"),
actionButton("btn",id=ns("button5"),label = "Show Output"),
actionButton("btn",id=ns("button6"),label = "Change Color"))),
# Show a plot of the generated distribution
mainPanel(
br(),br(),br(),
tags$p(strong(" ***** MY OUTPUT PANEL ***** ")),
tags$div(id=ns('div2'),class="main")
)
)
}
moduleTest <- function(input, output, session){
#scatter plot
onclick('button1',
plot(mtcars$disp, mtcars$mpg,xlab="Engine displacement",
ylab="mpg", main="MPG vs engine displacement",
las=1))
#or onclick('button1',qplot(disp, mpg, data=mtcars,main="MPG vs engine displacement"))
#histogram
onclick('button2',hist(mtcars$disp,xlab="Engine displacement", breaks = 5))
#bar plot
onclick('button3',barplot(mtcars$disp, main="Graph of displacement", names.arg = mtcars$mpg))
onclick('button4',hide('div2'))
onclick('button5',show('div2'))
onclick('button6',setBackgroundColor("blue"))
#---------- other method
#scatter plot
# observeEvent(input$button1,plot(mtcars$disp, mtcars$mpg,xlab="Engine displacement",
# ylab="mpg", main="MPG vs engine displacement", las=1))
#or onclick('button1',qplot(disp, mpg, data=mtcars,main="MPG vs engine displacement"))
#histogram
#observeEvent(input$button2,hist(mtcars$disp,xlab="Engine displacement", breaks = 5))
#bar plot
#observeEvent(input$button3,barplot(mtcars$disp, main="Graph of displacement", names.arg = mtcars$mpg))
#observeEvent(input$button4,hide("div2"))
#observeEvent(input$button5,show("div2"))
#observeEvent(input$button6,setBackgroundColor("blue"))
}
ui <- fluidPage(
useShinyjs(),
moduleTestUI('test')
)
# Define server logic required to draw a histogram
server <- function(input, output) {
}
# Run the application
shinyApp(ui = ui, server = server)
I confess, I did post this question over on RStudio three days ago but it has not had enough love yet, so I'm trying again here. I hope that's okay. The original question is here (the text is the same in both, I'm just being transparent). https://community.rstudio.com/t/selecting-rows-from-a-dt-table-using-crosstalk-in-shiny/4079
So I would like to brush across points in D3Scatter and use it to filter the rows of a datatable produced using the DT package with crosstalk.
Just like this, which totally works outside of shiny:
library(crosstalk)
library(d3scatter)
library(DT)
shared_iris <- SharedData$new(iris)
bscols(d3scatter(shared_iris, ~Petal.Length, ~Petal.Width, ~Species, width = "100%",
x_lim = range(iris$Petal.Length), y_lim = range(iris$Petal.Width)),
datatable(shared_iris))
But when I put it in Shiny, I can select points on the scatter from the table, but not vice versa:
library(shiny)
library(crosstalk)
library(d3scatter)
library(DT)
ui <- fluidPage(
fluidRow(
column(6, d3scatterOutput("scatter1")),
column(6, DT::dataTableOutput("scatter2"))
)
)
server <- function(input, output, session) {
jittered_iris <- reactive({
iris
})
shared_iris <- SharedData$new(jittered_iris)
output$scatter1 <- renderD3scatter({
d3scatter(shared_iris, ~Petal.Length, ~Petal.Width, ~Species, width = "100%",
x_lim = range(iris$Petal.Length), y_lim = range(iris$Petal.Width))
})
output$scatter2 <- DT::renderDataTable({
datatable(shared_iris)
})
}
shinyApp(ui, server)
They’ve got it working here: https://rstudio-pubs-static.s3.amazonaws.com/215948_95c1ab86ad334d2f82856d9e5ebc16af.html
I’m at a loss. I feel like I’ve tried everything. Any clues anyone?
Thanks,
Crosstalk integration in DT only works with client-side processing . Try DT::renderDataTable with server = FALSE
library(shiny)
library(crosstalk)
library(d3scatter)
library(DT)
ui <- fluidPage(
fluidRow(
column(6, d3scatterOutput("scatter1")),
column(6, DT::dataTableOutput("scatter2"))
)
)
server <- function(input, output, session) {
jittered_iris <- reactive({
iris
})
shared_iris <- SharedData$new(jittered_iris)
output$scatter1 <- renderD3scatter({
d3scatter(shared_iris, ~Petal.Length, ~Petal.Width, ~Species, width = "100%",
x_lim = range(iris$Petal.Length), y_lim = range(iris$Petal.Width))
})
output$scatter2 <- DT::renderDataTable({
datatable(shared_iris)
}, server = FALSE)
}
shinyApp(ui, server)
DT should throw an error when using Crosstalk with server-side processing
Error in widgetFunc: Crosstalk only works with DT client mode: DT::renderDataTable({...}, server=FALSE)
but I think that broke here: https://github.com/rstudio/DT/commit/893708ca10def9cfe0733598019b62a8230fc52b
Guess I can file an issue on this if no one else has.
I have created several likert scales with R package "likert" and would like to plot each one of them in shiny when the radio button of that one is selected.
The sample scales is:
a <- sample(rep((1:5),5))
b <- sample(rep((1:5),5))
c <- data.frame(sapply(data.frame(a), factor))
d <- data.frame(sapply(data.frame(b), factor))
scaledc <- likert(c)
scaledd <- likert(d)
The shiny codes are:
ui <- fluidPage(
titlePanel("Survey"),
sidebarLayout(
sidebarPanel(
selectInput("type",
"Plot Type",
choices = c("Likert"="bar",
"Density"="density",
"Heatmap"="heat"), selected="Likert"),
radioButtons("qtype",
"Question type:",
c("Agreement"="scaledc", "Helpfulness"="scaledd"),
selected="scaledc")
),
# Show a plot of the generated distribution
mainPanel(
tabsetPanel(
tabPanel("Yearly Data", plotOutput("distPlot1"))
)
)
)
)
#server
server <- function(input, output) {
output$distPlot1 <- renderPlot({plot(input$qtype, type=input$type)+
ggtitle("How agree are you with following statements?")}, height = 1000)
}
The shiny returned error "need finite 'ylim' values." I think it's becaue the input$qtype doesn't pass the correct information to the plot command, but I don't know how to fix it. Thank you for advance!
I've just solved the problem.
The missing codes in server are:
scale <- reactive({
get(input$qtype)
})
output$dat <- renderPrint({
scale()
})
And then do plot with scale() will show selected plot.
I'm working on leaflet with shiny. The tools is basic, i have a map with some markers (coming from a table with LONG and LAT).
What I want to do is to open a table or a graph when i click on the marker.
Is there a simple way to do it?
Do you have a really simple example: you have a maker on a map, you click on the marker, and there is a plot or a table or jpeg that s opening?
Here is another example, taken from here and a little bit adapted. When you click on a marker, the table below will change accordingly.
Apart from that, a good resource is this manual here:
https://rstudio.github.io/leaflet/shiny.html
library(leaflet)
library(shiny)
myData <- data.frame(
lat = c(54.406486, 53.406486),
lng = c(-2.925284, -1.925284),
id = c(1,2)
)
ui <- fluidPage(
leafletOutput("map"),
p(),
tableOutput("myTable")
)
server <- shinyServer(function(input, output) {
data <- reactiveValues(clickedMarker=NULL)
# produce the basic leaflet map with single marker
output$map <- renderLeaflet(
leaflet() %>%
addProviderTiles("CartoDB.Positron") %>%
addCircleMarkers(lat = myData$lat, lng = myData$lng, layerId = myData$id)
)
# observe the marker click info and print to console when it is changed.
observeEvent(input$map_marker_click,{
print("observed map_marker_click")
data$clickedMarker <- input$map_marker_click
print(data$clickedMarker)
output$myTable <- renderTable({
return(
subset(myData,id == data$clickedMarker$id)
)
})
})
})
shinyApp(ui, server)
There is a leaflet example file here:
https://github.com/rstudio/shiny-examples/blob/ca20e6b3a6be9d5e75cfb2fcba12dd02384d49e3/063-superzip-example/server.R
# When map is clicked, show a popup with city info
observe({
leafletProxy("map") %>% clearPopups()
event <- input$map_shape_click
if (is.null(event))
return()
isolate({
showZipcodePopup(event$id, event$lat, event$lng)
})
})
Online demo (see what happens when you click on a bubble):
http://shiny.rstudio.com/gallery/superzip-example.html
On the client side, whenever a click on a marker takes place, JavaScript takes this event and communicates with the Shiny server-side which can handle it as input$map_shape_click.