How to get mouse over labels in a shiny ggplot2 polar plot? - r

I'm struggeling with mouse over labels for my ggplot 2 polar plot in shiny.
Simple version of my code (without mouse over labels):
library(dplyr)
library(shiny)
library(ggplot2)
# Define UI for application that plots features of iris
ui <- fluidPage(
br(),
# Sidebar layout
sidebarLayout(
# Inputs
sidebarPanel(
),
# Outputs
mainPanel(
plotOutput(outputId = "radarplot"),
br()
)
)
)
# Define server function required to create the radarplot
server <- function(input, output) {
# Create radarplot with iris dataset
output$radarplot <- renderPlot ({
iris %>%
ggplot(.) + geom_histogram(aes(y = Petal.Width, x = Species, fill = Species),
binwidth= 1,
stat= 'identity',
alpha = 1 ) +
geom_histogram(aes(y = Sepal.Width, x = Species, fill = Species),
binwidth= 1,
stat= 'identity',
alpha = 0.3) +
coord_polar()
})
}
# Create a Shiny app object
shinyApp(ui = ui, server = server)
I made a version using plotly, trying to add mouse over labels. But then I don't get a radar plot.
library(dplyr)
library(shiny)
library(ggplot2)
library(plotly)
# Define UI for application that plots features of iris
ui <- fluidPage(
br(),
# Sidebar layout
sidebarLayout(
# Inputs
sidebarPanel(
),
# Outputs
mainPanel(
plotlyOutput(outputId = "radarplot"),
br()
)
)
)
# Define server function required to create the radarplot
server <- function(input, output) {
# Create radarplot with iris dataset
output$radarplot <- renderPlotly ({
iris %>%
ggplot(.) + geom_histogram(aes(y = Petal.Width, x = Species, fill = Species),
binwidth= 1,
stat= 'identity',
alpha = 1 ) +
geom_histogram(aes(y = Sepal.Width, x = Species, fill = Species),
binwidth= 1,
stat= 'identity',
alpha = 0.3) +
coord_polar()
})
}
# Create a Shiny app object
shinyApp(ui = ui, server = server)
Ideally I want the mouse over label to give output about Petal.Width, Sepal.Width and Species when hovering over a particular Species 'wing'.
Any suggestions how to get these mouse over labels?

Here is an example of this using the ggiraph package.
First the tooltip needs to be created.
library(tidyverse)
iris_group_means <-
iris %>%
group_by(Species) %>%
summarise_all(mean) %>%
mutate(tooltip = sprintf("Sepal Length: %1.2f\nSepal Width: %1.2f\nPetal Length: %1.2f\nPetal Width: %1.2f",
Sepal.Length, Sepal.Width, Petal.Length, Petal.Width)) %>%
select(Species, tooltip)
Then this tooltip just needs to be provided as an aesthetic, and instead of geom_histogram, use the ggiraph::geom_histogram_interactive function.
my_gg <-
iris %>%
ggplot() +
geom_histogram(aes(y = Petal.Width, x = Species, fill = Species),
binwidth= 1,
stat= 'identity',
alpha = 1 ) +
ggiraph::geom_histogram_interactive(aes(y = Sepal.Width, x = Species, fill = Species, tooltip = tooltip),
binwidth= 1,
stat= 'identity',
alpha = 0.3) +
coord_polar()
ggiraph::ggiraph(code = print(my_gg))
This can then be used in Shiny. A few other steps are involved and there is a separate ggiraph::renderggiraph function to use. Details are on the ggiraph site
Here is the final Shiny code. I don't use shiny much so this can probably be improved upon, but it worked for me.
# Define UI for application that plots features of iris
ui <- fluidPage(
br(),
# Sidebar layout
sidebarLayout(
# Inputs
sidebarPanel(
),
# Outputs
mainPanel(
ggiraph::ggiraphOutput(outputId = "radarplot"),
br()
)
)
)
# Define server function required to create the radarplot
server <- function(input, output) {
# Create radarplot with iris dataset
output$radarplot <- ggiraph::renderggiraph ({
iris_group_means <-
iris %>%
group_by(Species) %>%
summarise_all(mean) %>%
mutate(tooltip = sprintf("Sepal Length: %1.2f\nSepal Width: %1.2f\nPetal Length: %1.2f\nPetal Width: %1.2f",
Sepal.Length, Sepal.Width, Petal.Length, Petal.Width)) %>%
select(Species, tooltip)
iris <-
left_join(iris, iris_group_means, by="Species")
my_gg <-
iris %>%
ggplot() +
geom_histogram(aes(y = Petal.Width, x = Species, fill = Species),
binwidth= 1,
stat= 'identity',
alpha = 1 ) +
ggiraph::geom_histogram_interactive(aes(y = Sepal.Width, x = Species, fill = Species, tooltip = tooltip),
binwidth= 1,
stat= 'identity',
alpha = 0.3) +
coord_polar()
ggiraph::ggiraph(code = print(my_gg))
})
}
# Create a Shiny app object
shinyApp(ui = ui, server = server)

Related

Tooltip in percent stacked barchart

I am trying to format my ggplotly tooltip in a percent stacked barchart. In order to do this, I am editing a 'text' parameter in 'aes'
library(scales)
library(tidyverse)
library(plotly)
library(ggplot2)
library(shiny)
#Define dataframe
weeknum <- c(1,1,1,1,2,2,2,2,3,3,3,3)
channel <- rep(c("a", "b"), 6)
product <- c(rep("x",6), rep("y",6))
data <- data.frame(weeknum, channel, product)
# Define UI
ui <- fluidPage(theme = shinytheme("flatly"),
mainPanel(
h1("plot"),
plotlyOutput(outputId = "plot_1", height = "800px")
))
# Define server function
server <- function(input, output) {
output$plot_1 <- renderPlotly({
p1 <- data %>%
ggplot(aes(x=weeknum, fill=channel, text = paste('share:', percent(..count..), "<br> channel", fill))) +
geom_bar(position = "fill", stat ='count')+
facet_grid(rows = vars(product))
fig1 <- ggplotly(p1, tooltip = "text")
fig1
})
}
# Create Shiny object
shinyApp(ui = ui, server = server)
so here I got only count * 100% in the tooltip. I know I need to divide it by a dynamic height of a bar, because in this dashboard I'm gonna use some filters. Question is how can I do this? (..count..)/sum(..count..) doesn't work.
Since you did not provide a reproducible example, I created one using mtcars data set. This is how I would approach your task.
library(ggplot2)
library(dplyr)
plot <- mtcars %>%
count(cyl, am, name = "count") %>%
mutate(across(c(cyl, am), as.character)) %>%
ggplot(
aes(x = cyl, fill= am, y = count,
text = paste('share:', scales::percent(count/sum(count)), '<br>AM:', am)
)
) +
geom_col(position = "fill")
plotly::ggplotly(plot, tooltip = "text")

Add trendline data to Shiny Plotly on hover

I'm creating a plot using ggplotly() and I'd like the Spearman's rank correlation [I'm storing here as the reactive value rho] to appear when hovering over the line created with geom_smooth. I found an article on the plotly website for doing this in python (https://plot.ly/python/linear-fits/) but I'm unsure how to achieve this in R. Any help or leads appreciated!!
library(shiny)
library(plotly)
ui <- fluidPage(
mainPanel(plotlyOutput("line_plot"),
verbatimTextOutput("rho"))
)
# Define server logic required to draw a histogram
server <- function(input, output) {
# calculate rho to be printed over line
rho <- reactive({ cor.test(x = iris$Sepal.Length, y = iris$Sepal.Width, method='spearman')[[4]] })
output$rho <- renderText(paste0("rho: ", rho()))
output$line_plot <- renderPlotly({
p <- ggplotly(
ggplot(iris, aes(x = Sepal.Length, y = Sepal.Width)) +
geom_point() +
# would I add the tooltip text here?
# I know I need it to be:
# "<b> rho: </b>", rho(), "<br/>",
geom_smooth(method=lm, se=FALSE, color = "red") +
theme_minimal()
)
})
}
# Run the application
shinyApp(ui = ui, server = server)
You can add the unoffical aesthetics text:
library(shiny)
library(plotly)
ui <- fluidPage(
mainPanel(plotlyOutput("line_plot"),
verbatimTextOutput("rho"))
)
# Define server logic required to draw a histogram
server <- function(input, output) {
# calculate rho to be printed over line
rho <- reactive({ cor.test(x = iris$Sepal.Length, y = iris$Sepal.Width, method='spearman')[[4]] })
output$rho <- renderText(paste0("rho: ", rho()))
output$line_plot <- renderPlotly({
p <- ggplotly(
ggplot(iris, aes(x = Sepal.Length, y = Sepal.Width)) +
geom_point() +
geom_smooth(method=lm, se=FALSE, color = "red", aes(text = paste0("<b> rho: </b>", rho()))) +
theme_minimal()
)
})
}
# Run the application
shinyApp(ui = ui, server = server)

Error: Evaluation error: argument of length 0. R Shiny 1:nrow

My file is one set of game data and PitchNo tells the pitch of the game. I am trying to generate plots of each batter's pitches seen in a game and I have labeled the PitchNo in the ggplot function. I want my plot for each batter to label the pitches seen, say 1-10, but instead it is still labeling them as the PitchNo of the game.
I added Batter$PitchNo <- 1:nrow(Batter) in my reactive filter. That line of code works in normal R but I cannot seem to find a way to make in work in a Shiny app.
library(shiny)
library(tidyverse)
GameDataFile <- read_csv("GameDataFile.csv")
GameDataFile %>% group_by(PitchNo)
playerlist <- sort(unique(GameDataFile$Batter))
ui = fluidPage(
titlePanel("Title"),
sidebarLayout(
sidebarPanel(
selectInput(
inputId="Batter1",
label="Player:",
choices = playerlist)
),
mainPanel(
plotOutput("myZone")
)))
server = function(input, output){
output$myZone <- renderPlot({
GameDataFile$PlateLocSide <- (GameDataFile$PlateLocSide * -1)
newdata <- reactive({
GameDataFile %>% filter(
Batter %in% c(input$Batter1),
Batter$PitchNo <- 1:nrow(Batter)) # Error is here
})
ggplot(data = newdata(), aes(x = PlateLocSide, y = PlateLocHeight)) +
xlim(-2.5,2.5) + ylim(0,5) + scale_fill_viridis_c() + geom_point() +
labs(x = "", y = "") + facet_wrap(~ Batter, ncol = 2) +
geom_text(aes(label = PitchNo), vjust = -0.5) + theme_bw() +
theme(strip.text = element_text(size=20, face="bold"))
}, width=400, height=500)
}
shinyApp(ui = ui, server = server)

Interactive plot for group data using R

All,
In order to graph data in many groups(categories):
data(iris)
library(dplyr)
iris_new <- select(iris, -Species)
ggplot(iris, aes(x = Sepal.Length, y = Sepal.Width)) +
geom_point(data = iris_new, colour = "grey70") +
geom_point(aes(colour = Species)) +
facet_wrap(~Species)
I didn't make interactive plots before, but I would like to know a way to allow me to make the above graph interactively. For example, in stead of showing the data using facet, I would like to have a bottom-like thing or scroll down list function that I can click on to highlight the data of different groups interactively. Each time I click on a certain group name (like those used for the legend), I can see the group data are highlighted and other data are greyed out. Any ideas here? Thank you.
You can make interactive displays via shiny. See here: https://shiny.rstudio.com/
Here's code that you can run:
library(shiny)
library(dplyr)
library(ggplot2)
data(iris)
ui <- fluidPage(
selectInput('species','Species',c("setosa","versicolor","virginica")),
plotOutput("plot")
)
server <- function(input, output) {
iris_new <- select(iris, -Species)
output$plot <- renderPlot({
ggplot(iris, aes(x = Sepal.Length, y = Sepal.Width)) +
geom_point(data = iris_new, colour = "grey70") +
geom_point(data=iris[iris$Species==input$species,],aes(colour = Species))
})
}
shinyApp(ui = ui, server = server)

shiny: plotting selected columns from dataset to graphs

Just discovering shiny apps but this is driving me insane.......I have looked at numerous examples of server.R and ui.R code and cannot figure out what I am doing wrong. Apologies in advance if it's something very basic..........
Taking the iris dataset as an example, I want to plot one column against another, something simple using qplot or preferably ggplot
However, using qplot I get this:
and using ggplot2, I get the error:
I don't think I need the reactive function as I'm not subsetting the dataset, just extracting columns to plot.
server.R code
library(shiny)
library(shinyapps)
library(ggplot2)
shinyServer(function(input, output, session) {
output$text1 <- renderText({input$id1})
output$text2 <- renderText({input$select1})
output$plot1 <- renderPlot({
g <- qplot(Sepal.Length, input$select1, data = iris)
print(g)
})
})
or using ggplot function to replace the qplot call
g <- ggplot(iris, aes(x = Sepal.Length, y = input$select1))
g <- g + geom_line(col = "green", lwd =1) +
labs(x = "Date", y = "Ranking") +
theme_bw() + scale_y_reverse()
ui.R code
library(shiny)
library(shinyapps)
data(iris)
opts <- unique(colnames(iris))
opts <- opts[-1] ## want to keep Sepal.Length as the x values
shinyUI(pageWithSidebar(
headerPanel('test with iris database'),
sidebarPanel(
selectInput(inputId = "select1", label = "select",
choices = opts),
textInput(inputId = "id1", label = "Input Text", "")
),
mainPanel(
p('Output text1'),
textOutput('text1'),
textOutput('text2'),
plotOutput('plot1')
)
))
Change your aes statement to aes_string and make x a string. This should fix the problem.
g <- ggplot(iris, aes_string(x = "Sepal.Length", y = input$select1))
g <- g + geom_line(col = "green", lwd =1) +
labs(x = "Date", y = "Ranking") +
theme_bw() + scale_y_reverse()

Resources