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() # 两个图并排
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 显示交互组件
常见报错与解决
| 报错信息 | 原因 | 解决方法 |
|---|
BokehDeprecationWarning | Bokeh 版本不匹配 | 更新 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: 更简单,社区更大,快速原型更快