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

Shiny应用中ggplotly转换失败:矩阵列数不匹配错误求助

Shiny中ggplotly转换sf地图时报错:矩阵列数不匹配

在Shiny应用中使用ggplotly转换ggplot绘制的sf地图时,应用卡顿(显示shinycssloaders加载动画),无法生成ggplotly对象。通过browser()调试确认:ggplot对象Bmap可正常绘制,但执行Bmaply <- ggplotly(p=Bmap)时触发以下错误:

Error in (function (..., deparse.level = 1) : number of columns of matrices must match (see arg 4)

server.R 相关代码

output$biomass.map <- plotly::renderPlotly({

     if (req(input$update==TRUE & 'map' %in% input$visual2)) {
        print('Creating biomass map')
        ids  <- c('fips.huc8')
        
        # get.along transposes and converts dt to Mg
        blong.sf <- mixed() %>%
         select(all_of(c(ids, 'supply.Mg'))) %>%
         get.along(ids=ids) 
        
        # map uses 'value' column
         Bmap <- map.fips.huc(blong.sf)
         browser()
         Bmaply <- ggplotly(p=Bmap)
         return(Bmaply)
     }
})

ui.R 相关代码(移除Spinner后问题仍存在)

## Display biomass map, data table, and supply curve
        ## withSpinner color needs to be hex
        tabPanel(h4("biomass"), id=2, value=2,
          fluidRow(
            column(plotlyOutput("biomass.map", width="100%") %>% withSpinner(color= "#00FFFF"), width=12, offset=0, div(style="padding: 0px 0px; margin:0%"), align='left'),
            column(DT::dataTableOutput("data.table"), width=12, offset=0, div(style="padding: 0px 0px; margin:0%"), align='left')
            #column(plotOutput("biomass.supply", width="100%"), width=12, offset=0, div(style="padding: 0px 0px; margin:0%"), align='left')
          )
        ),

Shiny运行日志

Listening on http://127.0.0.1:3849
[1] "Creating biomass map"
[1] "generating mixed-crop buffer data"
[1] "mixed: adding values"
Warning: Error in <Anonymous>: number of columns of matrices must match (see arg 4)
  118: h
  117: .handleSimpleError
  116: <Anonymous>
  115: do.call
  114: cbind
  113: coord_4
  112: st_coordinates.sfc
  111: sf::st_coordinates
  110: fortify_sf
  109: structure
  108: prefix_class
  107: to_basic.GeomSf
  106: to_basic
  105: layers2traces
  104: gg2list
  103: ggplotly.ggplot
  102: ggplotly
  101: ::
plotly
renderPlotly [C:\Users\zij\Dropbox (ORNL)\MyProjects\Bioenergy\EcoServices-Valuation\ShinyVEST-v3-incentives/server.R#73]
  100: func
   99: promises::is.promising
   98: getFromNamespace("prepareWidget", "plotly")
   97: shinyRenderWidget
   96: func
   95: force
   94: withVisible
   93: withCallingHandlers
   92: domain$wrapSync
   91: promises::with_promise_domain
   90: captureStackTraces
   89: doTryCatch
   88: tryCatchOne
   87: tryCatchList
   86: tryCatch
   85: do
   84: hybrid_chain
   83: renderFunc
   82: output$biomass.map
   81: ..stacktraceon..
   80: orig
   79: func
   78: withCallingHandlers
   77: domain$wrapSync
   76: promises::with_promise_domain
   75: captureStackTraces
   74: withCallingHandlers
   73: shinyCallingHandlers
   72: force
   71: domain$wrapSync
   70: promises::with_promise_domain
   69: private$withCurrentOutput
   68: force
   67: withVisible
   66: withCallingHandlers
   65: domain$wrapSync
   64: promises::with_promise_domain
   63: captureStackTraces
   62: doTryCatch
   61: tryCatchOne
   60: tryCatchList
   59: tryCatch
   58: do
   57: hybrid_chain
   56: force
   55: withVisible
   54: withCallingHandlers
   53: domain$wrapSync
   52: promises::with_promise_domain
   51: captureStackTraces
   50: doTryCatch
   49: tryCatchOne
   48: tryCatchList
   47: tryCatch
   46: do
   45: hybrid_chain
   44: observe
   43: <observer:output$biomass.map>
   42: contextFunc
   41: env$runWith
   40: force
   39: domain$wrapSync
   38: promises::with_promise_domain
   37: withReactiveDomain
   36: domain$wrapSync
   35: promises::with_promise_domain
   34: ctx$run
   33: run
   32: withCallingHandlers
   31: domain$wrapSync
   30: promises::with_promise_domain
   29: captureStackTraces
   28: withCallingHandlers
   27: shinyCallingHandlers
   26: force
   25: withVisible
   24: withCallingHandlers
   23: domain$wrapSync
   22: promises::with_promise_domain
   21: captureStackTraces
   20: doTryCatch
   19: tryCatchOne
   18: tryCatchList
   17: tryCatch
   16: do
   15: hybrid_chain
   14: flushCallback
   13: FUN
   12: lapply
   11: ctx$executeFlushCallbacks
   10: .getReactiveEnvironment()$flush
    9: flushReact
    8: serviceApp
    7: ..stacktracefloor..
    6: withCallingHandlers
    5: domain$wrapSync
    4: promises::with_promise_domain
    3: captureStackTraces
    2: ..stacktraceoff..
    1: runApp

排查方向

  • 检查几何数据一致性:在browser()中执行sf::st_geometry_type(Bmap$data),确认所有要素几何类型统一。若存在混合类型(如多边形+空几何),用sf::st_cast()统一为目标类型(如st_cast("POLYGON")),同时用sf::st_is_valid(Bmap$data)检查几何有效性,清理无效要素。
  • 验证输入数据:检查get.along()处理后的blong.sf是否有缺失值、重复ID或空几何列,必要时过滤异常行。
  • 版本兼容性:更新plotly、sf、ggplot2到最新稳定版,旧版本plotly对sf图层的转换支持存在已知bug。
  • 简化测试:在browser()中用极简代码重新生成ggplot并转换:
    test_plot <- ggplot(Bmap$data) + geom_sf(aes(fill = value))
    ggplotly(test_plot)
    
    逐步排除复杂图层设置(如自定义主题、标注)的影响。

内容的提问来源于stack exchange,提问作者Yetta Jager

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 11:43:18