Есть ли способ получить участок объекта ggplot, не сохраняя его в памяти? [Дубликат]

Чтобы изменить размер линий вискеров, мы можем использовать аргумент width = 0.5 внутри функции: stat_boxplot

set.seed(42)
df <- data.frame(cond = factor(rep(c("A", "B"), each = 500)), 
                 value = c(rnorm(500, mean = 1, sd = 0.2), 
                           rnorm(500, mean = 1.5, sd = 0.1))) 

library(ggplot2)
ggplot(df, aes(x = cond, y = value)) +
       stat_boxplot(geom = "errorbar", width = 0.5) +  
       geom_boxplot() 

8
задан Abhi 12 June 2014 в 21:54
поделиться

3 ответа

Предполагая, что вы используете ggplot (что с Shiny, я бы сделал ставку, это справедливое предположение).

  1. Создайте пустой список для хранения вашего grob, скажем Plist.
  2. Когда пользователь запрашивает график, создайте хэш на основе блестящих входов
  3. Проверьте, сохранен ли граф, например hash %in% names(Plist)
  4. Если да, обслуживать этот график
  5. Если нет, сгенерируйте граф, сохраните grob в списке, назовите элемент хешем, например Plist[hash] <- new_graph
5
ответ дан Ricardo Saporta 25 August 2018 в 08:41
поделиться

Хотя оба ответа на этот вопрос очень хорошие, я хотел добавить еще один, используя блестящие модули . Следующий модуль принимает функцию графика и реактивную версию своих аргументов в качестве входных данных. В конце do.call(plotfun, args()) используется для создания графика.

library(shiny)

cachePlot <- function(input, output, session, plotfun, args, width = 480, height = 480,
                      dir = tempdir(), prefix = "cachedplot", deleteonexit = TRUE){
  hash <- function(args) digest::digest(args)

  output$plot <- renderImage({
    args <- args()
    if (!is.list(args)) args <- list(args)
    imgpath <- file.path(dir, paste0(prefix, "-", hash(args), ".png"))

    if(!file.exists(imgpath)){
      png(imgpath, width = width, height = height)
      do.call(plotfun, args)
      dev.off()
    }
    list(src = imgpath)
  }, deleteFile = FALSE)

  if (deleteonexit) session$onSessionEnded(function(){
    imgfiles <- list.files(tempdir(), pattern = prefix, full.names = TRUE)
    file.remove(imgfiles)
  })
}

cachePlotUI <- function(id){
  ns <- NS(id)
  imageOutput(ns("plot"))
}

Как мы видим, модуль удаляет файлы изображений, созданные при необходимости, и дает возможность использовать настраиваемый каталог-кеширование в случае

Для примера использования я использую пример hist(faithful[, 2]), как и Stedy.

histfaithful <- function(bins, col){
  message("calling histfaithful with args ", bins, " and ", col) 
  x  <- faithful[, 2]
  bins <- seq(min(x), max(x), length.out = bins + 1)
  hist(x, breaks = bins, col = col, border = 'white')
}

shinyApp(
  ui = fluidPage(
    inputPanel(
      sliderInput("bins", "bins", 5, 30, 10, 1),
      selectInput("col", "color", c("blue", "red"))
    ),
    cachePlotUI("cachedPlot")
  ),
  server = function(input, output, session){
    callModule(
      cachePlot, "cachedPlot", histfaithful, 
      args = reactive(list(bins = input$bins, col = input$col))
    )
  }
)
2
ответ дан Gregor de Cillia 25 August 2018 в 08:41
поделиться

Ответ от Ricardo Saporta очень хороший, и я использовал для решения аналогичной проблемы, но я также хотел добавить решение для кода.

Для кэширования я использовал digest::digest(), где я только что накормил список параметров для этого конкретного графа для этой функции для создания хеш-строки. Первоначально я думал, что мне нужно будет извлечь хэш-строку из observe(), а затем использовать stat if / else, чтобы определить, следует ли мне отправить его на renderImage() или renderPlot() на основе того, было ли ранее создано изображение. Некоторое время я с этим справился, а затем наткнулся на использование renderImage(). Это не идеальная подстановка изображения, а более близкая для целей этой демонстрации.

ui.R

library(shiny)

fluidPage(
  sidebarLayout(
    sidebarPanel(
       sliderInput("bins",
                   "Number of bins:",
                   min = 1,
                   max = 50,
                   value = 25),
      selectInput("plot_color", "Barplot color",
                   c("green"="green",
                      "blue"="blue"))
    ),
    mainPanel(
       plotOutput("distPlot", width='100%', height='480px')
    )
  )
)

и server.R

library(shiny)

function(input, output) {

base <- reactive({
  fn <- digest::digest(c(input$bins, input$plot_color))
  fn})

output$distPlot <- renderImage({
    filename <- paste0(base(), ".png")
    if(filename %in% list.files()){
      list(src=filename)
    } else {
    x  <- faithful[, 2]
    bins <- seq(min(x), max(x), length.out = input$bins + 1)
    png(filename)
    hist(x, breaks = bins, col = input$plot_color, border = 'white')
    dev.off()
list(src=filename)
    }

  }, deleteFile = FALSE)
}
2
ответ дан Stedy 25 August 2018 в 08:41
поделиться
Другие вопросы по тегам:

Похожие вопросы: