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

改用ggplot+ggplotly替代plot_ly实现Shiny饼图需求

解决Shiny中用ggplot+ggplotly实现交互式饼图的问题

我来帮你搞定这个需求!你想替换原来出问题的plot_ly代码,改用ggplot绘制饼图再转成交互式的ggplotly,同时要在饼图扇区里显示客户数量和占比,每次切换设施时自动更新,对吧?咱们一步步调整你的代码:

关键调整点

  • 先正确聚合数据:对选中的FacilityName分组,统计OriginId的数量,再计算每个类别的占比,把这两个信息组合成显示用的标签
  • 用ggplot绘制饼图,再通过ggplotly()转换为交互式图表
  • 优化代码结构,确保数据处理和绘图逻辑清晰

完整修正代码

# 加载所需包
library(shinydashboard)
library(plotly)
library(dplyr)
library(data.table)

# 构造测试数据
OriginId=c("INT","EXT","INT","INT","EXT","INT","EXT","INT")
FacilityName=c("t1","t1","t2","t2","t1","t3","t4","t5")
FacId=c("t1","t1","t2","t2","t1","t3","t4","t5")
Testdata2<-data.frame(OriginId,FacilityName,FacId)

# UI部分
ui <- dashboardPage(skin = "black",
  dashboardHeader(title = img(src="Logo1.jpg", height = 50, align = "left")),
  dashboardSidebar(
    sidebarMenu(
      menuItem("Dashboard", tabName = "dashboard", icon = icon("dashboard"))
    )
  ),
  dashboardBody(
    tabItems(
      tabItem(tabName = "dashboard",
              fluidRow(
                box(title = "Verhältnis interner / externer Aufträge", 
                    status = "primary", solidHeader = TRUE, 
                    plotlyOutput("pie",height = 250)),
                uiOutput("var")
              )
      )
    )
  )
)

# Server部分
server <- function(input, output,session) {
  
  # 生成设施选择下拉框
  output$var<-renderUI({
    selectInput("variable", h4("Abteilung wählen:"),
                choices = Testdata2 %>% distinct(FacilityName) %>% pull(FacilityName),
                selected = 1)
  })
  
  # 处理数据并绘制交互式饼图
  output$pie<-renderPlotly({
    # 过滤选中设施的数据,聚合统计并计算占比
    plot_data <- Testdata2 %>%
      filter(FacilityName == input$variable) %>%
      count(OriginId, name = "KundenAnzahl") %>%
      mutate(Prozentsatz = scales::percent(KundenAnzahl / sum(KundenAnzahl)),
             # 组合显示标签:数量 + 占比
             Label = paste(KundenAnzahl, "Kunden", "\n", Prozentsatz))
    
    # 用ggplot绘制饼图
    p <- ggplot(plot_data, aes(x = "", y = KundenAnzahl, fill = OriginId)) +
      geom_col(width = 1, color = "white") +
      coord_polar("y", start = 0) +
      geom_text(aes(label = Label), position = position_stack(vjust = 0.5)) +
      labs(title = input$variable) +
      theme_void() + # 去掉多余的坐标轴和背景
      theme(plot.title = element_text(hjust = 0.5))
    
    # 转换为交互式ggplotly图表
    ggplotly(p, tooltip = c("fill", "KundenAnzahl", "Prozentsatz")) %>%
      layout(showlegend = FALSE)
  })
}

# 运行Shiny应用
shinyApp(ui, server)

代码说明

  1. 数据处理部分:用dplyr的filter选中当前设施的数据,count统计每个OriginId的客户数量,mutate计算占比并生成显示标签(包含客户数和百分比)
  2. ggplot绘图:用geom_col配合coord_polar生成饼图,geom_text把标签放在扇区中心位置,theme_void去掉不必要的元素让饼图更简洁
  3. ggplotly转换:把静态ggplot转为交互式图表,设置tooltip显示关键信息,同时关闭图例(和你原来的需求一致)

这样调整后,每次切换设施,饼图都会自动更新,扇区里清晰显示客户数量和占比,交互体验也符合你的需求~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 06:49:02