跳转至

Panel Python 仪表盘

Panel 是 HoloViz 生态中的仪表盘框架,最大特色是支持几乎所有 Python 可视化库(Matplotlib、Plotly、Bokeh、HoloViews 等),还有拖拽布局和强大的响应式 API,适合需要多种图表库混用的数据科学家。

核心知识点

知识点说明
工具定位Python 数据仪表盘框架
最新版本v1.8.10(2026 年)
开发团队HoloViz 社区(Anaconda 支持)
核心优势支持所有主流绘图库、响应式 API、拖拽布局
生态定位HoloViz 套件成员(hvPlot、HoloViews、Datashader)
许可证BSD 3-Clause

安装配置

# pip 安装
pip install panel                      # 安装 Panel

# conda 安装(推荐,依赖更完整)
conda install -c conda-forge panel

# 安装完整 HoloViz 生态
conda install -c conda-forge holoviz

# Jupyter 支持
panel extension                        # 在 Notebook 中启用 Panel

# 启动 Panel 应用
panel serve app.py                     # 启动服务
panel serve app.py --autoreload        # 开发模式(自动重载)

基本使用

1. 第一个 Panel 应用

import panel as pn                     # 导入 Panel
pn.extension()                         # 初始化(Jupyter 中必须)

# 最简单的应用
pn.panel("# Hello Panel! 🧬").servable()  # Markdown 文本

# 交互式 Widget
slider = pn.widgets.IntSlider(         # 整数滑块
    name="样本数量",
    start=10, end=100, value=50
)
pn.Column(                             # 垂直布局
    "## 参数设置",
    slider,
    pn.bind(lambda x: f"你选择了 {x} 个样本", slider)  # 响应式绑定
).servable()
# 运行
panel serve app.py --show              # 启动并打开浏览器

2. 支持多种绘图库

import panel as pn
import matplotlib.pyplot as plt        # Matplotlib
import plotly.express as px            # Plotly
import pandas as pd

pn.extension("plotly")                 # 启用 Plotly 支持

df = pd.DataFrame({
    "物种": ["Bacteroidetes", "Firmicutes", "Proteobacteria"],
    "丰度": [35, 28, 15]
})

# Matplotlib 图表
fig_mpl, ax = plt.subplots(figsize=(6, 4))
ax.bar(df["物种"], df["丰度"])
ax.set_title("Matplotlib 柱状图")
mpl_pane = pn.pane.Matplotlib(fig_mpl)  # Panel 包装 Matplotlib

# Plotly 图表
fig_plotly = px.pie(df, values="丰度", names="物种", title="Plotly 饼图")
plotly_pane = pn.pane.Plotly(fig_plotly)  # Panel 包装 Plotly

# 并排显示
pn.Row(mpl_pane, plotly_pane).servable()  # 两个图并排

3. 常用 Widget

import panel as pn
pn.extension()

# 输入组件
text = pn.widgets.TextInput(name="样本名", value="Sample1")  # 文本输入
num = pn.widgets.FloatInput(name="阈值", value=0.05)  # 数值输入
select = pn.widgets.Select(name="方法", options=["PCoA", "NMDS", "t-SNE"])  # 下拉
multi = pn.widgets.MultiChoice(name="选择物种",   # 多选
    options=["Bacteroidetes", "Firmicutes", "Proteobacteria"])
slider = pn.widgets.FloatSlider(name="阈值", start=0, end=1, step=0.01)  # 滑块
toggle = pn.widgets.Toggle(name="显示标签", value=True)  # 开关
file = pn.widgets.FileInput(accept=".csv,.tsv")  # 文件上传

# 布局
layout = pn.Column(                    # 垂直布局
    pn.Row(text, num),                 # 水平布局
    select,
    slider,
    multi
)
layout.servable()

高级用法

1. 响应式编程(Panel 的核心)

import panel as pn
import pandas as pd
import plotly.express as px

pn.extension("plotly")

# 数据
df = pd.DataFrame({
    "物种": ["A", "B", "C", "D", "E"] * 2,
    "丰度": [35, 28, 15, 12, 10, 30, 32, 18, 10, 10],
    "组别": ["健康"] * 5 + ["疾病"] * 5
})

# Widget
group_select = pn.widgets.Select(name="组别", options=["全部", "健康", "疾病"])
chart_type = pn.widgets.RadioButtonGroup(
    name="图表类型", options=["柱状图", "饼图"], value="柱状图"
)

# 响应式函数:Widget 变化时自动更新
@pn.depends(group_select, chart_type)  # 依赖这两个 Widget
def update_chart(group, ctype):
    filtered = df if group == "全部" else df[df["组别"] == group]
    if ctype == "柱状图":
        return px.bar(filtered, x="物种", y="丰度", title=f"{group} - 柱状图")
    else:
        return px.pie(filtered, values="丰度", names="物种", title=f"{group} - 饼图")

# 组装应用
app = pn.Column(
    "# 🧬 菌群分析仪表盘",
    pn.Row(group_select, chart_type),  # 控件行
    update_chart                       # 响应式图表
)
app.servable()

2. 模板(快速美化)

import panel as pn

# Panel 内置多种模板
template = pn.template.FastListTemplate(  # 美观的列表模板
    title="菌群分析平台",
    sidebar=[                          # 侧边栏
        pn.widgets.Select(name="数据集", options=["Dataset1", "Dataset2"]),
        pn.widgets.FloatSlider(name="阈值", start=0, end=1),
    ],
    main=[                             # 主区域
        pn.pane.Markdown("## 分析结果"),
        pn.pane.Plotly(fig_plotly),
    ]
)
template.servable()

# 可用模板:FastListTemplate, MaterialTemplate, BootstrapTemplate,
#           VanillaTemplate, ReactTemplate 等

3. 拖拽布局(EditableTemplate)

import panel as pn

# v1.8 新增:拖拽式布局
template = pn.template.EditableTemplate(  # 可拖拽的模板
    title="自定义仪表盘"
)
# 用户可以在界面中拖拽调整组件位置
template.servable()

4. 在 Jupyter 中使用

import panel as pn
pn.extension()                         # Jupyter 中初始化

# 直接在 Notebook 中交互
slider = pn.widgets.IntSlider(name="值", start=0, end=100)
output = pn.bind(lambda x: f"当前值: {x}", slider)

pn.Row(slider, output)                 # 直接在 Notebook 显示交互组件

常见报错与解决

报错信息原因解决方法
BokehDeprecationWarningBokeh 版本不匹配更新 Panel 和 Bokeh
Jupyter 中不显示未调用 extension先执行 pn.extension()
Plotly 图表空白未启用扩展pn.extension("plotly")
回调不触发依赖声明错误检查 @pn.depends() 参数

速查表

# ===== Panel 速查表 =====

import panel as pn
pn.extension()                  # 初始化

# Widget
pn.widgets.TextInput()          # 文本
pn.widgets.FloatSlider()        # 滑块
pn.widgets.Select()             # 下拉
pn.widgets.MultiChoice()        # 多选
pn.widgets.Toggle()             # 开关
pn.widgets.FileInput()          # 文件
pn.widgets.Button()             # 按钮
pn.widgets.DatePicker()         # 日期

# 显示面板
pn.pane.Markdown("# 标题")     # Markdown
pn.pane.Matplotlib(fig)        # Matplotlib
pn.pane.Plotly(fig)            # Plotly
pn.pane.HTML("<b>HTML</b>")    # HTML
pn.pane.DataFrame(df)          # 表格

# 布局
pn.Row(a, b)                   # 水平
pn.Column(a, b)                # 垂直
pn.Tabs(("Tab1", a))           # 标签页
pn.GridSpec(ncols=3)           # 网格

# 响应式
@pn.depends(widget)            # 依赖声明
pn.bind(fn, widget)            # 函数绑定

# 模板
pn.template.FastListTemplate() # 列表模板
pn.template.MaterialTemplate() # Material 模板

# 运行
panel serve app.py --show      # 启动服务
panel serve app.py --autoreload  # 开发模式

# Panel vs Streamlit
# Panel: 支持所有绑图库,更灵活,学习曲线高
# Streamlit: 更简单,社区更大,快速原型更快