You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Shiny应用技术问题咨询:rglWidgetOutput保存、弹窗移除及日志优化

Got it, let's break down each of your Shiny + rgl issues with concrete, workable solutions—no more trial-and-error headaches:

1. Save rglwidgetOutput to any custom file + log the action

To let users save the 3D plot to a path of their choice and log the action, you can combine Shiny's download utilities with rgl's widget saving function, plus simple file-based logging.

Option 1: Basic browser download (with auto-generated filename)

Add a download button to your UI, then handle the save and logging in the server:

# UI
fluidPage(
  rglwidgetOutput("plot3d"),
  downloadButton("save_rgl", "Save 3D Plot")
)

# Server
server <- function(input, output) {
  output$plot3d <- renderRglwidget({
    open3d()
    plot3d(rnorm(100), rnorm(100), rnorm(100))
    rglwidget()
  })

  output$save_rgl <- downloadHandler(
    filename = function() {
      paste0("3d_plot_", format(Sys.time(), "%Y%m%d_%H%M%S"), ".html")
    },
    content = function(file) {
      # Save the rgl widget to the temp file (browser will prompt to save it)
      saveWidget(rglwidget(), file)
      
      # Log the save action: append to a log file
      log_entry <- paste0(Sys.time(), " - Successfully saved 3D plot to: ", normalizePath(file), "\n")
      cat(log_entry, file = "shiny_app_log.txt", append = TRUE)
    }
  )
}

Option 2: Let users pick any save path

If you want full custom path control, use the shinyFiles package to let users browse their filesystem:

# Install first if needed: install.packages("shinyFiles")
library(shinyFiles)

# UI
fluidPage(
  rglwidgetOutput("plot3d"),
  shinySaveButton("save_custom", "Save to Custom Path", "Choose save location", filetype = list(html = "html"))
)

# Server
server <- function(input, output, session) {
  output$plot3d <- renderRglwidget({
    open3d()
    plot3d(rnorm(100), rnorm(100), rnorm(100))
    rglwidget()
  })

  # Set up filesystem access (here we let users access their home directory)
  shinyFileSave(input, "save_custom", roots = c(Home = "~"), session = session)

  observeEvent(input$save_custom, {
    req(input$save_custom)
    # Parse the user-selected path
    save_path <- parseSavePath(roots = c(Home = "~"), input$save_custom)$datapath
    
    # Save the widget
    saveWidget(rglwidget(), save_path)
    
    # Log the custom save
    log_entry <- paste0(Sys.time(), " - Saved 3D plot to custom path: ", normalizePath(save_path), "\n")
    cat(log_entry, file = "shiny_app_log.txt", append = TRUE)
  })
}

2. Remove the small "focus" window on app startup

That tiny pop-up is rgl's default empty device window. To get rid of it, just tell rgl to use a NULL (headless) device right after loading the package:

library(shiny)
library(rgl)

# Critical line: disable rgl's default visible device
rgl.useNULL(TRUE)

# Rest of your app code goes here
ui <- fluidPage(rglwidgetOutput("plot3d"))
server <- function(input, output) {
  output$plot3d <- renderRglwidget({
    open3d()
    plot3d(rnorm(100), rnorm(100), rnorm(100))
    rglwidget()
  })
}
shinyApp(ui, server)

This makes rgl render the plot in the background without popping up that annoying small window.

3. Rename "data_planes" in logs for better readability

How you fix this depends on how you're generating the log entries:

If you're hardcoding "data_planes" in log strings

Simply replace the raw string with your preferred friendly name:

# Original log code
cat(Sys.time(), " - Processed data_planes\n", file = "app_log.txt", append = TRUE)

# Modified log code (use whatever name you want)
cat(Sys.time(), " - Processed 3D Plane Dataset\n", file = "app_log.txt", append = TRUE)

If "data_planes" is a variable name being logged

If you're pulling the name programmatically (e.g., with deparse(substitute())), override it with a custom label:

# Original code that logs the variable name
data_planes <- your_dataset_here
log_msg <- paste(Sys.time(), " - Processed object: ", deparse(substitute(data_planes)), "\n")
cat(log_msg, file = "app_log.txt", append = TRUE)

# Modified code with custom name
log_msg <- paste(Sys.time(), " - Processed object: 3D Plane Dataset\n")
cat(log_msg, file = "app_log.txt", append = TRUE)

Bonus: Attach a friendly label to the data object

If you want to keep the variable name but log a nicer label, add a comment to the object:

data_planes <- your_dataset_here
# Attach a human-readable label
comment(data_planes) <- "3D Plane Dataset"

# Log the comment instead of the variable name
log_msg <- paste(Sys.time(), " - Processed object: ", comment(data_planes), "\n")
cat(log_msg, file = "app_log.txt", append = TRUE)

内容的提问来源于stack exchange,提问作者Ingo Bittersmann

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 10:00:55