Reputation: 109
I have a basketball half court created in ggplot that I've embedded inside a sidebarPanel in Shiny and I would like to highlight "zones" of the court based on user input. I was thinking I could use something along the lines of renderUI coupled with geom_rect() to get what I want, but nothing I've tried seems to work. Can anyone help with this?
I've attached an image link that is hopefully helpful in supplementing my explanation above along with current code.
Thank you!
teams <- c("Hawks","Celtics","Nets","Hornets","Bulls","Cavaliers",
"Mavericks","Nuggets","Pistons","Warriors","Rockets","Pacers",
"Clippers","Lakers","Grizzlies","Heat","Bucks","Timberwolves",
"Pelicans","Knicks","Thunder","Magic","76ers","Suns","Trail
Blazers", "Kings","Spurs","Raptors","Jazz","Wizards")
server <- function(input, output) {
output$half_court <- renderPlot({
ggplot() + geom_polygon(data = court[court$side==1,], aes(x = x, y = y,
group = group), col = "gray") +
coord_equal() +
xlim(-2,50) +
ylim(-2,50) +
scale_x_continuous(breaks = c(0, 25, 50)) +
scale_y_continuous(breaks = c(0, 12.5, 25, 37.5, 50)) +
xlab("") + ylab("") +
theme(axis.text.x = element_blank(),
axis.text.y = element_blank(), axis.ticks.x = element_blank(),
axis.ticks.y = element_blank(), axis.title = element_blank()) +
theme(panel.background = element_rect(fill = 'white')) +
geom_rect(aes_string(xmin = 0, xmax = 10, ymin = 37.6, ymax = 47), fill
= "yellow", alpha = 0.20) +
geom_rect(aes_string(xmin = 40, xmax = 50, ymin = 0, ymax = 9.4), fill
= "green", alpha = 0.20)
}, bg = "transparent")
}
ui <- fluidPage(
titlePanel(title=div(img(src="primary.png", height = 50, width =
50),strong("Database"))),
sidebarLayout(
sidebarPanel(
selectInput("season", "Season",c("","2016","2015","2014")),
selectInput("team", "Team 1",c("",teams)),
selectInput("team", "Team 2",c("",teams)),
selectInput("pass", "Pass Location",c("",1:25)),
selectInput("poss", "Possession Location",c("",1:25)),
plotOutput(outputId = "half_court")
),
mainPanel()
)
)
shinyApp(ui = ui, server = server)
Upvotes: 3
Views: 433
Reputation: 17719
Using base plot you could have a transparent plot (renderPlot({...}, bg="transparent")
), add transparent rectangles (rect(..., col = rgb(0, 50, 255, 50, maxColorValue = 256))
) to it and add the picture as a background via CSS (HTML("#plot{background:url(https://...)}))
).
For a sample app, see below:
bckpic <- "https://thedatagame.files.wordpress.com/2016/03/nba_court.jpg"
pos <- function(x, y){
xx <- x1 <- (x - 1)*5 + c(0, 5)
yy <- 25 - ((y - 1)*5 + c(0, 5))
return(c(xx[1], yy[2], xx[2], yy[1]))
}
ui <- fluidPage(
tags$style(type='text/css', HTML("#plot{background:url(https://thedatagame.files.wordpress.com/2016/03/nba_court.jpg);
background-size: 200px 200px;
background-repeat: no-repeat;}")),
selectInput("pass", "Pass Location", 1:25),
selectInput("possess", "Possession Location", 1:25, 25),
uiOutput("style"),
plotOutput("plot")
)
server <- function(input, output){
output$plot <- renderPlot({
par(mar = c(0,0,0,0))
plot(0, 0, ylim = c(0,25), xlim = c(0, 25), type='p', yaxt = "n",
xaxt = "n", xlab = "", ylab = "")
nr <- as.numeric(input$pass)
posi <- pos(ifelse(nr%%5 > 0, nr%%5, 5),ceiling(nr/5))
rect(posi[1], posi[2], posi[3], posi[4], col = rgb(0, 50, 255, 50, maxColorValue = 256))
nr <- as.numeric(input$possess)
posi <- pos(ifelse(nr%%5 > 0, nr%%5, 5),ceiling(nr/5))
rect(posi[1], posi[2], posi[3], posi[4], col = rgb(255, 50, 0, 50, maxColorValue = 256))
}, bg="transparent", width = 200, height = 200)
}
runApp(shinyApp(ui, server), launch.browser = TRUE)
Upvotes: 1