ich eine App mit shiny
machte, die Benutzer erlaubt, klicken Punkte auf einem Bild auszuwählen. Ich verwende ggplot2
, um die ausgewählten Punkte als rote Punkte auf dem Bild anzuzeigen.ggplot2 in glänzend, dann ändert Bild/Plot neu zu laden, ohne sie komplett neu zu erstellen
Ich habe dies funktioniert ziemlich nah an der Art, die ich will, nur dass jedes Mal, wenn der Benutzer einen neuen Punkt klickt, das gesamte Bild neu geladen wird *. Idealerweise würde ich die Daten bei jedem Klick neu plotten, aber nicht das gesamte Bild neu laden.
Meine Frage ist, ist es möglich, die Plotpunkte reaktiv neu geladen zu haben, aber allein das Hintergrundbild verlassen (da es nicht zwischen Klicks ändern wird)?
Meine eigentliche App ist komplizierter als diese, aber hier ist mein bestes Beispiel für ein minimales reproduzierbares Beispiel des Problems, das ich ansprechen möchte (beachten Sie, dass Sie image.file
einstellen müssen, um auf eine jpg - Datei zu zeigen Maschine, um diese zu laufen, ich weiß nicht, wie das Bild machen selbst reproduzierbar, sorry):
library(ggplot2)
library(jpeg)
library(grid)
library(shiny)
#### pre-run setup ####
# set up a function for loading an image file as a grob
grob_image <- function(file) {
grid::rasterGrob(jpeg::readJPEG(file), interpolate = TRUE)
}
# initiate a ggplot theme for use in plotting
# (just getting rid of everything so we only see the image itself)
theme_empty <- theme_bw()
theme_empty$line <- element_blank()
theme_empty$rect <- element_blank()
theme_empty$strip.text <- element_blank()
theme_empty$axis.text <- element_blank()
theme_empty$plot.title <- element_blank()
theme_empty$axis.title <- element_blank()
# set the image input file
image.file <- "session2_ebbTriggerCountMap.jpg"
#### UI ####
ui <- fluidPage(
# display the image, with any click-points
fluidRow(
plotOutput("plot",
click = "image_click"
)
)
)
### SERVER ####
server <- function(input, output, session) {
# initialise a data.frame for collecting click points
data.thisimage <- data.frame(x = rep(NA_real_, 100L), y = rep(NA_real_, 100L))
# initalise the plot (this is the image on which to put any points we get)
# the `geom_blank` here is to set up the x and y axes as per the width and height of the image
img <- grob_image(image.file)
base <- ggplot() +
geom_blank(data = data.frame(x = c(0, dim(img$raster)[2]), y = c(0, dim(img$raster)[1])),
mapping = aes(x = x, y = y)
) +
theme_empty +
annotation_custom(grob = img)
# plot the image
output$plot <- renderPlot({
base
})
#### click action ####
# watch for a mouse click (point selected on the plot)
observeEvent(input$image_click, {
# add a row of data to the data frame
data.thisimage[ which(is.na(data.thisimage$x))[1L], ] <<- c(
input$image_click$x, input$image_click$y
)
# re-render the plot with the new data
output$plot <<- renderPlot({
base +
geom_point(data = data.thisimage[ !is.na(data.thisimage$x), ],
mapping = aes(x = as.numeric(x), y = as.numeric(y)),
colour = "red")
})
})
}
shinyApp(ui, server)
Da das Bild mit jedem Mausklick neu geladen wird, ich habe Probleme mit Reaktivität der UI Antizipation , CPU-Last und Datenübertragungslast. Gibt es eine Möglichkeit, das zu lindern?
* es ist wohl offensichtlich aus dem Code selbst, aber ich habe es mir selbst bewiesen, indem die CPU-Auslastung zu beobachten beim Klicken immer und immer wieder mit einem großen ish Bild geladen.
HINWEIS das nächste, was ich zu meinem Problem finden konnte, war diese SO Frage. Leider löst es nicht das Problem des Neuladens des Bildes, sondern beschleunigt nur das Rendern von Datenpunkten, was hier nicht mein Problem ist. Update large plots in Shiny without Re-Rendering
FYI erhalte ich 'Fehler in img $ Raster: Objekt vom Typ ' Schließung 'ist nicht Teilmenge' beim Versuch, ru n this – DataJack
Sorry, das ist mein schlechtes. Ich habe es versäumt, eine Änderung vorzunehmen, als ich das Beispiel "minimal" gemacht habe, ich habe eine Änderung vorgenommen, und es sollte jetzt funktionieren. – rosscova