I'm trying to embed an RChart into a shiny app. I'm specifically using the nPlot function to create a type=scatterChart NVD3 style plot. In the NVD3 website example below, there are two pieces of functionality I am interested in getting to work in my RCharts shiny app:
http://nvd3.org/ghpages/scatter.html
It appears that a "rug" is included along the x-axis and y-axis of the above example, demonstrating marginally where the x and y points occur most frequently along their respective supports.
Further, when one clicks on the chart and hovers over a specific point a vertical and horizontal line appear noting the (x,y) location of the corresponding point.
Does anyone know how to expand my code below to achieve these two pieces of functionality. Shiny server.r and ui.r scripts are included below.
## server.r
library(rCharts)
library(shiny)
x <- rnorm(100)
y <- rnorm(100)
dat <- as.data.frame(cbind(x,y))
shinyServer(function(input, output) {
output$myChart <- renderChart({
p1 <- nPlot(y ~ x, data = dat, type = "scatterChart")
p1$addParams(dom = 'myChart')
p1$params$height=400
p1$params$width=650
return(p1)
})
})
## ui.R
library(rCharts)
library(shiny)
shinyUI(pageWithSidebar(
headerPanel("rCharts: Interactive Charts from R using NVD3.js"),
sidebarPanel(
wellPanel(
helpText( "Look at the pretty graph"
)
),
wellPanel(
helpText( "Look at the pretty graph"
)
),
wellPanel(
helpText( "Look at the pretty graph"
)
)
),
mainPanel(
div(class='wrapper',
tags$style(".Nvd3{ height: 400px;}"),
showOutput("myChart","Nvd3")
)
)
))
Thanks in advance for any advice you can provide.
This can be achieved using the following code:
p1$chart(
showDistX = TRUE,
showDistY = TRUE
)
return(p1)
Also, just as a note, while direct manipulation of p1$params works, it might be safer to specify height and width in this way:
p1 <- nPlot(
y ~ x,
data = dat,
type = "scatterChart",
height = 400,
width = 650
)
Related
Is there a way to link user input (x-axis, y-axis, colour etc) to the gganimate graph in R shiny? So that when the user selects a different input (x-axis, y-axis, colour, etc.) from the drop-down list. gganimate graph will be filled with different x-axis, y-axis, colour, etc. so that it can be changed accordingly?
The coding I tried as below. And there is error due to the variable name I saved in UI (xValue, yValue, colorValue etc which are putting in ggplot function) does not apply in the Serve...
The idea of UI code come from here: https://shiny.rstudio.com/articles/layout-guide.html
And it would display sth like this:
library(shiny)
library(shinythemes)
library(palmerpenguins)
library(gganimate)
library(dplyr)
library(tidyr)
library(ggplot2)
library(gapminder)
data(package = 'palmerpenguins')
ui <- fluidPage(
navbarPage(
"Animated penguins data",
tabPanel("Navbar 2",
##########
imageOutput('plot'),
hr(),
fluidRow(
column(3,
h4("Diamonds Explorer"),
sliderInput('sampleSize', 'Sample Size',
min=1, max=nrow(penguins), value=min(1000, nrow(penguins)),
step=500, round=0),
br(),
checkboxInput('jitter', 'Jitter'),
checkboxInput('smooth', 'Smooth')
),
column(4, offset = 1,
xValue -> selectInput('x', 'X', names(penguins)),
yValue -> selectInput('y', 'Y', names(penguins), names(penguins)[[2]]),
colorValue -> selectInput('color', 'Color', c('None', names(penguins)))
),
column(4,
rowValue -> selectInput('facet_row', 'Facet Row', c(None='.', names(penguins))),
columnValue -> selectInput('facet_col', 'Facet Column', c(None='.', names(penguins)))
)
)
#########
),
) # navbarPage
) # fluidPage
The idea of serve come from here: How to create and display an animated GIF in Shiny?
The server is sth. like this
# Define server function
server <- function(input, output) {
##########################################
output$plot <- renderImage({
# A temp file to save the output.
# This file will be removed later by renderImage
outfile <- tempfile(fileext='.gif')
# now make the animation
p = myPenguins %>%
ggplot(
aes(xValue, yValue, color = colorValue)) +
geom_point() +
#geom_line() +
facet_grid(rows = vars(rowValue), cols = vars(columnValue))+
theme_bw()+
#theme_minimal() +
transition_time(year)+
labs(title = "Year: {frame_time}")+
view_follow()#+
anim_save("outfile.gif", animate(p)) # New
# Return a list containing the filename
list(src = "outfile.gif",
contentType = 'image/gif')
}, deleteFile = TRUE)
################################################################
}
shinyApp(ui = ui, server = server)
Your code is still far from minimal and I don't have many of the packages you reference, but I think the following will illustrate the techniques that will allow you to do what you want. I've based my code on the diamonds dataset, which is part of ggplot2.
Your problem is due to the fact that Shiny input widgets (generally) return strings, whereas ggplot functions expect symbols as their argument. This is a feature of the tidyverse's use of non-standard evaluation (NSE).
As a result, the interface between Shiny and the tidyverse can be perplexing when you first come across it. One solution is to use the bang-bang operator (!!) and the sym function.
The following app displays a faceted scatter plot in which the user has complete control over the variables that
are plotted on the x axis
are plotted on the y-axis
define the colours of the plotted points
define the facet rows
define the facet columns
library(shiny)
library(tidyverse)
ui <- fluidPage(
selectInput("x", "X variable:", names(diamonds)),
selectInput("y", "Y variable", names(diamonds), selected="price"),
selectInput("colour", "Colour: ", names(diamonds), selected="color"),
selectInput("facetRows", "Facet rows: ", names(diamonds), selected="clarity"),
selectInput("facetCols", "Facet columns", names(diamonds), selected="cut"),
plotOutput("plot")
)
server <- function(input, output) {
output$plot <- renderPlot({
diamonds %>%
ggplot() +
geom_point(aes(x=!!sym(input$x), y=!!sym(input$y), colour=!!sym(input$colour))) +
facet_grid(rows=vars(!!sym(input$facetRows)), cols=vars(!!sym(input$facetCols)))
})
}
shinyApp(ui = ui, server = server)
Note that the diamonds dataset is quite large and a poor choice of variables for any of the five roles I mention above can lead to lengthy delays!
I think this provides an answer to your question, but I'm not entirely sure because of the many disparate features in your code (eg saving a GIF file, use of gganimate, reference to gapminder) that do not seem relevant to the question of using UI inputs in a call to renderPlot. If I haven't given you what you want, please refine your question and code so that they reference only the elements that are critical to the fundamental issue.
This post will help you construct a minimal reproducible example.
I have used shiny for several small scale project and am now giving a try to the shinydashboard package which looks rather promising. I also want to integrate interactive plot using plotly (although other libraries can be considered in the future).
I have no problem running examples integrating plotly in shiny (example) but face problems when attempting to achieve a similar results with shinydashboard.
For example, the code below (app.R) is not working properly.
library(shiny)
library(shinydashboard)
library(plotly)
library(ggplot2)
data(movies, package = "ggplot2")
minx <- min(movies$rating)
maxx <- max(movies$rating)
#######
####### UI
#######
ui <- dashboardPage(
############# Header
dashboardHeader(title = "Test"),
############# Sidebar
dashboardSidebar(
sidebarMenu(
menuItem("Dashboard", tabName = "dashboard", icon = icon("dashboard"))
)
),
############# Dashboard body
dashboardBody(
# Boxes need to be put in a row (or column)
fluidRow(
box(plotOutput("plot1"), width=6, height=500),
box(plotOutput("plot2"), width=6, height=500)
)
)
)
#######
####### Server
#######
server <- function(input, output, session) {
output$plot1 <- renderPlot({
# a simple histogram of movie ratings
p <- plot_ly(movies, x = rating, autobinx = F, type = "histogram",
xbins = list(start = minx, end = maxx, size = 2))
# style the xaxis
layout(p, xaxis = list(title = "Ratings", range = c(minx, maxx), autorange = F,
autotick = F, tick0 = minx, dtick = 2))
})
output$plot2 <- renderPlot({
hist(movies$rating, col="blue")
})
}
shinyApp(ui, server)
The page is supposed to display two similar plots: one generated with plotly, the other with R base. The second one is displayed properly but the plotly one is displayed in Rstudio viewer panel. If I run the App on a terminal using the runApp() function, one webpage opens for the dashboard and another one using only for the plotly interactive plot.
I have tried to create some reactive plots (plots change in function of the content of some shiny controls such as slide bars) and the plot opened either in the viewer or another browser window/tab is updated.
So everything seems to work, the only problem is that the plotly plot is not inserted in the dashboard but in a different location (viewer or other tab), which, of course, is a problem.
Despite of my research, I could not find a solution to the problem (or even people mentioning it...). Any clue?
Check again the tutorial carefully, I think you need to replace in the ui
box(plotOutput("plot1"), width=6, height=500)
by
box(plotlyOutput("plot1"), width=6, height=500)
And in the server just replace
output$plot1 <- renderPlot({
......
by
output$plot1 <- renderPlotly({
....
I have a app, where I want to use rCharts and polycharts, to create a plot with a tooltip. But the plot doesn't show up, when I load the shiny app, and I can't figure out why.
Here is my ui.R:
library(shiny)
require(rCharts)
shinyUI(fluidPage(
titlePanel("Please work..."),
sidebarLayout(
sidebarPanel( "Test:",
uiOutput("TestSelection")),
mainPanel("Plots (show me the money, please!):",
showOutput("tempplot","polycharts")
)
)
))
And here's my server.R:
library(shiny)
require(rCharts)
#Test of rcharts and shiny.
df1 <- read.csv("//KED-FILE/ASIC-Shared/users/jhertel/Work/R_workspace/oban_test_data.csv",quote="")
shinyServer(function(input, output, session){
output$TestSelection <- renderUI({
df <- df1
selectInput("TestSel", "Test Variable", ls(df, pattern = ".*?_meas|.*?_calc"))
})
output$tempplot <- renderChart2({
dataPlot <- df1[,c("DUT", input$TestSel, "Temperature")]
r1 <- rPlot(input$TestSel ~ Temperature,
data = dataPlot,
type = "point",
tooltip = "#!function(item){return item.DUT}!#",
sample = FALSE)
r1$guides(
x = list(
min = pretty( dataPlot$Temperature ) [1],
max = tail( pretty( dataPlot$Temperature ), 1 ),
numticks = length( pretty( dataPlot$Temperature ) ),
labels = pretty( dataPlot$Temperature )
),
y = list(
min = pretty( dataPlot[, input$TestSel] ) [1],
max = tail( pretty( dataPlot[, input$TestSel] ), 1 )
)
)
return(r1)
})
})
I've tried different things, such as options(RCHART_LIB = 'polycharts'), using as.formula around input$TestSel ~ Temperature, adding a reactive element on the TestSelection-ui, I've tried changing browser, from internal, to Firefox, to Chrome.
I am suspecting the input$TestSel ~ Temperature to be the reason, as when I inspect the javascript with Chrome, it doesn't look like input$TestSel has been interpreted to the desired value. But I am a total noob to javascript, so I wouldn't know. EDIT: I am fairly certain that my error occurs here, as setting the changing input$TestSel to a desired value results in the desired plot... Still don't know how to solve it, though.
When just using R the plot shows up as desired in the viewer.
I want to use the nPlot() function in RCharts to plot percentages of people falling into discrete groups, rather than frequencies.
For example: Using the HairEyeColor data/code below I am able to consider the percentage of people with different hair colors (my grouping variable), as a function of their eye color.
## server.r
library(rCharts)
library(shiny)
library(reshape)
HairEyeColor1 <- melt(round(prop.table(HairEyeColor[,,1],2)*100,2))
names(HairEyeColor1) <- c("Hair", "Eye", "Percent")
shinyServer(function(input, output) {
output$myChart <- renderChart({
p1 <- nPlot(Percent ~ Eye, group = "Hair", data = HairEyeColor1, type = multiBarChart")
p1$addParams(dom = 'myChart')
return(p1)
})
})
## ui.R
library(rCharts)
library(shiny)
shinyUI(pageWithSidebar(
headerPanel("rCharts: Interactive Charts from R using NVD3.js"),
sidebarPanel(
wellPanel(
helpText( "Look at the pretty graph"
)
),
wellPanel(
helpText( "Look at the pretty graph"
)
),
wellPanel(
helpText( "Look at the pretty graph"
)
)
),
mainPanel(
div(class='wrapper',
tags$style(".Nvd3{ height: 400px;}"),
showOutput("myChart","Nvd3")
)
)
))
Say I just wanted to look at a single factor, like Hair. Is there a way to plot their percentages using nPlot()?
prop.table(rowSums(HairEyeColor[,,1]))
Black Brown Red Blond
0.2007168 0.5125448 0.1218638 0.1648746
With type=multiBarChart I have tried:
p1 <- nPlot(Percent ~ , group = "Hair", data = HairEyeColor1, type = multiBarChart")
This fails entirely. I have also tried:
p1 <- nPlot(Percent ~ 1, group = "Hair", data = HairEyeColor1, type = multiBarChart")
This at least passes some graph to Shiny UI. But this looks hideous and functionality (appearance of X/Y-axis, clicking on graph) is all lost.
I thought this would be appropriate for nPlot(type=discreteBarChart) but the data layout for this seems to want a dataframe with a single factor variable. So I can't quite see how to trick nPlot(type=discreteBarChart) into taking a vector of proportions/percentages.
Any suggestions appreciated.
Here is how to do it with nPlot. You can see the resulting plot here. If you want to stack the bars by default, add the line n1$chart(stacked = TRUE) before you print the chart.
# prepare data
require(plyr)
dat = as.data.frame(HairEyeColor)
dat = ddply(dat, .(Hair), summarize, Freq = sum(Freq), Group = "A")
# draw chart
require(rCharts)
n1 <- nPlot(Freq ~ Group, data = dat, group = 'Hair', type = 'multiBarChart')
n1
I am trying to embed an RChart into a shiny app. Specifically, working with the function nPlot and the type=lineChart NVD3 feature. I am trying to plot 3 density curves for simulated Normal data. I am trying to achieve some of the functionality described in the example below:
http://nvd3.org/ghpages/line.html
My issues:
How to have different colours for different density curves?
How to have the feature to click on group variable (1), (2), (3) to effectively remove the selected density. Similar to clicking on "Sine Wave" (top right) in the example to remove the orange sine curve?
How to add x-axis and y-axis labels? My $params$xAxis= call does not work.
Below are my server.R and ui.R files:
## server.r
library(rCharts)
library(shiny)
x <-rnorm(1000,0,1)
y <-rnorm(1000,1,1)
z <-rnorm(1000,2,1)
out <- c(x,y,z)
grp <- c(rep(0,1000),rep(1,1000),rep(2,1000))
data <- as.data.frame(cbind(out,grp))
dens <- by(data$out, data$grp, density)
d <- unlist(c(dens[[1]][1][1], dens[[2]][1][1], dens[[3]][1][1]))
support <- unlist(c(dens[[1]][2][1], dens[[2]][2][1], dens[[3]][2][1]))
grpvar <- c(rep(0,length(unlist(dens[[1]][1][1]))), rep(1,length(unlist(dens[[2]][1][1]))), rep(2,length(unlist(dens[[3]][1][1]))))
dat <- as.data.frame(cbind(d,support,grpvar))
shinyServer(function(input, output) {
output$myChart <- renderChart({
p1 <- nPlot(support~d, group=grpvar, data = dat, type = "lineChart")
p1$addParams(dom = 'myChart')
p1$params$width = 600
p1$params$height = 400
p1$params$xAxis = "Support"
p1$params$yAxis = "Density"
p1$chart(tooltipContent = "#! function(key, x, y, e){
return '<b>Group</b>: ' + e.point.grpvar
} !#")
return(p1)
})
})
## ui.R
library(rCharts)
library(shiny)
shinyUI(pageWithSidebar(
headerPanel("rCharts: Interactive Charts from R using NVD3.js"),
sidebarPanel(
wellPanel(
helpText( "Look at the pretty graph"
)
),
wellPanel(
helpText( "Look at the pretty graph"
)
),
wellPanel(
helpText( "Look at the pretty graph"
)
)
),
mainPanel(
div(class='wrapper',
tags$style(".Nvd3{ height: 600px;}"),
showOutput("myChart","Nvd3")
)
)
))
Thanks in advance for any help/advice you can provide.
You will just need to add quotes around grpvar, so
p1 <- nPlot(support~d, group="grpvar", data = dat, type = "lineChart")