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

在Quarto仪表板嵌入Shinylive应用时遇Pyodide安装shiny包错误

问题分析与解决方案

核心问题拆解

  1. Shinylive环境依赖未正确安装:添加micropip.install('shiny')后未处理异步逻辑,且缺少Excel读取必需的openpyxl依赖
  2. UI违规调用Server端函数:UI代码直接调用Server内的dat()响应式函数,违反Shiny前后端分离规则
  3. 数据筛选语法错误:isin是方法需用括号调用,且输入控件ID与代码引用不匹配
  4. 文件路径适配问题:Shinylive独立模式下,路径处理需适配Pyodide文件系统逻辑

分步解决

1. 正确安装依赖

在Shinylive代码块最顶部添加异步安装逻辑,确保所有依赖在import前完成安装:

import micropip
await micropip.install(["shiny", "pandas", "numpy", "seaborn", "openpyxl"])

注:openpyxl是Pandas读取Excel的必需依赖,必须包含

2. 修正UI与Server交互逻辑

UI中初始将选择器设为空列表,在Server端通过update_select_input动态加载选项:

  • UI部分:将choices参数设为[]
  • Server部分:添加@reactive.effect装饰的函数更新选择器选项

3. 修复数据筛选语法错误

将错误的筛选代码:

dat().loc[dat()[['item']].isin[input.select_item()]]

替换为:

dat().loc[dat()['item'].isin(input.select_items())]

修正点:isin()用括号调用,控件ID统一为select_items,直接对item列进行匹配

4. 适配Shinylive文件路径

Shinylive独立模式下,通过Quarto的#| files:指令声明依赖文件,路径简化为相对路径即可:

#| files:
#|   - dat/filename.xlsx

修改后的完整代码

index.qmd中的Shinylive代码块

```{shinylive-python}
#| standalone: true
#| title: Grouped Bar Plot - NOV 2023
#| files:
#|   - dat/filename.xlsx

import micropip
await micropip.install(["shiny", "pandas", "numpy", "seaborn", "openpyxl"])

from shiny import *
import pandas as pd
import numpy as np
import seaborn as sns
    
# UI
app_ui = ui.page_fluid(
    ui.input_select(
        "select_items",
        "选择项目:",
        choices=[],  # 初始为空,由Server动态填充
        multiple = True
    ),
    ui.output_plot("plot")
)

# server
def server(input, output, session):
    @reactive.calc
    def dat():
        df_summary = pd.read_excel("dat/filename.xlsx", sheet_name="sheet_name", usecols="A:D", dtype={"item": str, "value": np.float64, "value2": np.float64})
        df_summary_grp = df_summary.melt(id_vars='item', value_vars=['value1', 'value2'], var_name='variable', value_name='values')
        return df_summary_grp

    @reactive.effect
    def _update_select():
        # 动态更新选择器选项
        update_select_input(session, "select_items", choices=dat()["item"].unique().tolist())

    @output
    @render.plot(alt="分组条形图")
    def plot():
        # 处理未选择任何项目的边界情况
        if not input.select_items():
            filtered_df = dat()
        else:
            filtered_df = dat().loc[dat()["item"].isin(input.select_items())]
            
        g_ax_item_grp = sns.barplot(y='item', x='values', hue='variable', data=filtered_df)
        g_ax_item_grp.set_xlabel(None)
        sns.move_legend(g_ax_item_grp, loc="lower center", bbox_to_anchor=(-.4,-.3), ncol=2, title=None, frameon=False)
        return g_ax_item_grp

# app
app = App(app_ui, server)
### 额外注意事项
- 确保`dat/filename.xlsx`文件存在于项目根目录下,Quarto会自动打包该文件到Shinylive环境
- `_quarto.yml`中的`filters: [shinylive]`配置无需修改

内容的提问来源于stack exchange,提问作者M. Wood
相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 09:53:16