QuTiP 5.3 量子系统可视化实战:从 Wigner 函数到 Bloch 球与求解器结果图的完整指南
【免费下载链接】scientific-agent-skillsTurn any AI agent into an AI Scientist. The #1 Agent Skills library for science, used by 190,000+ scientists worldwide. 165 ready-to-use validated skills plus 100+ scientific databases covering biology, chemistry, medicine, and drug discovery. Compatible with Cursor, Claude Code, Codex, Pi, Antigravity, and the open Agent Skills standard.项目地址: https://gitcode.com/GitHub_Trending/cl/scientific-agent-skills
本文基于 scientific-agent-skills 仓库中的 QuTiP 可视化参考文档,系统讲解 QuTiP 5.3 的相空间可视化(Wigner 函数、Husimi Q 函数)、Bloch 球、Fock 分布、矩阵诊断、求解器结果绘图、相关函数与频谱绘图、动画与图表导出的完整实战方法。读完本文,你将掌握 QuTiP 5.3 可视化 API 的正确调用约定(尤其是容易踩坑的相空间数组轴顺序)、每种绘图的数值审计要点,以及如何将可视化纳入可复现的量子动力学研究流程。
前置准备:锁定 QuTiP 5.3 与 graphics 附加依赖
本仓库的 QuTiP 技能面向QuTiP 5.3.0(2026-05-22 发布),要求 Python 3.11 或更新版本。QuTiP 5.3 的必需依赖为 NumPy(>=1.23.2)、SciPy(>=1.9.2,排除1.16.0与1.17.0)以及packaging。可视化所依赖的 Matplotlib 等绘图栈通过graphics 附加依赖提供,安装命令为:
uv pip install "qutip[graphics]==5.3.0"如果只是运行模拟而不需要绘图,可退化为uv pip install "qutip==5.3.0"。仓库的 SKILL.md 建议为可复现实验创建独立环境并固定每一个直接依赖;当需要冻结传递依赖时,还应配合uv pip compile生成锁文件。仓库内脚本 _common.py 将支持版本硬编码为QUTIP_VERSION = "5.3.0",并会在导入时校验已安装版本与此一致,避免因版本漂移导致 API 差异(例如wigner的offset参数与QFunc的行为均为 5.3 特性)。
需要特别强调的是:绘图是诊断与沟通的产物,不能替代归一化、正定性、收敛性与不确定度检查。文末会给出与仓库配套的审计脚本用法,帮助你在"画图之前"先把物理与数值关卡。
相空间坐标约定与轴顺序:最容易踩的第一个坑
对于 QuTiP 的振子相空间函数,默认缩放为
[ a = \tfrac12 g(x + i y), \qquad g=\sqrt{2}, ]
这等价于 (\hbar=2/g^2=1)。也就是说,默认约定下相位空间坐标直接对应 (\hbar=1) 下的位置与动量标度。
QuTiP 5.3 返回数组的轴顺序(官方 5.3 release notes 明确澄清过这一点):
array[j, k] <-> yvec[j], xvec[k]这一约定同时适用于wigner、qfunc以及类接口QFunc。因此,传给 Matplotlib 时必须把xvec放在水平方向、yvec放在竖直方向:
image = ax.pcolormesh(xvec, yvec, values, shading="auto")不要凭习惯随意转置(np.transpose);当你把xvec与yvec设置成不同长度(例如xvec取 201 个点、yvec取 161 个点)并验证values.shape == (len(yvec), len(xvec))时,轴顺序错误会立刻暴露。该约定与仓库 SKILL.md 中"稳态、频谱与相空间"一节的断言一致,也与 visualization.md 的推荐用法互相印证。
Wigner 函数:四种种方法、offset 参数与数值自检
当前签名与基础绘图
wigner在 5.3 中的完整签名为:
wigner(psi, xvec, yvec=None, method="clenshaw", g=sqrt(2), sparse=False, parfor=False, offset=0)一个完整的绘图示例:
import numpy as np import matplotlib.pyplot as plt from qutip import coherent, wigner N = 30 state = coherent(N, 1.5) # 振幅 alpha=1.5 的相干态 xvec = np.linspace(-5.0, 5.0, 201) # 水平轴 201 个点 yvec = np.linspace(-4.0, 4.0, 161) # 竖直轴 161 个点(非对称,用于校验轴顺序) W = wigner(state, xvec, yvec, method="clenshaw") fig, ax = plt.subplots() limit = float(np.max(np.abs(W))) # 对称色标,突出负值区域 mesh = ax.pcolormesh( xvec, yvec, W, shading="auto", cmap="RdBu_r", vmin=-limit, vmax=limit, ) ax.set(xlabel="x", ylabel="y", title="Wigner function") fig.colorbar(mesh, ax=ax) fig.tight_layout()四种计算方法的取舍
| 方法 | 特点与适用场景 |
|---|---|
clenshaw | 鲁棒默认值,尤其在高激发(高光子数)时表现稳定 |
iterative | 递推方法 |
laguerre | 对稀疏的高维态可能有帮助 |
fft | 在内部自行计算 y 坐标,返回值形式与前三者不同 |
从源码结构看,fft路径改变了输入输出契约(y 网格由函数内部生成),因此选用时需单独阅读其文档并适配返回形式。
5.3 新增的offset参数
offset是 5.3 新增参数,用于支持首个被表示的数态编号不为零的 Fock 表象(例如截断时从较高光子数开始的态)。当你的模型在截断时把基态排除在表示之外时,应显式传入正确的offset,否则相空间函数会按错误的数态编号计算。
Wigner 图的数值自检清单
绘制 Wigner 函数前(后)应执行的数值检查:
- 扫描 Hilbert 截断维数与相空间范围:确认 Wigner 图在更宽的截断下形态稳定;
- 增加网格密度:验证细网格下峰值与负值区域不再变化;
- 用文档给出的坐标缩放做归一化校验:即利用 (a = g(x+iy)/2) 的关系核对积分/归一化结果;
- 区分数值容差附近的极小负值与稳健的 Wigner 负性:截断、网格与浮点误差都会引入 (O(10^{-15})) 量级的小负值,这与物理上可论证的 Wigner 负性是两回事;
- 当 x 与 y 共享物理单位时保持数据宽高比相等(
ax.set_aspect("equal")或等价手段),否则圆对称态会被拉伸成椭圆。
便捷绘图函数plot_wigner
from qutip import plot_wigner fig, ax = plot_wigner( state, xvec=xvec, yvec=yvec, projection="2d", colorbar=True, )应使用返回的fig, ax继续定制(设置标题、轴标签、保存),而不要依赖全局绘图状态(如plt.gca()/plt.gcf()),这在可复用代码与并发环境中尤其重要。
Husimi Q 函数:qfunc与类接口QFunc
单个态的qfunc
qfunc(state, xvec, yvec, g=sqrt(2), precompute_memory=1024)from qutip import qfunc Q = qfunc(state, xvec, yvec) assert Q.shape == (len(yvec), len(xvec)) fig, ax = plt.subplots() mesh = ax.pcolormesh(xvec, yvec, Q, shading="auto", cmap="viridis") fig.colorbar(mesh, ax=ax)Q 函数在精确算术下是非负的,但绘图仍然需要检查网格截断、绘图范围与格点密度——特别是当态包含高激发成分时,超出xvec/yvec范围的分布会被截掉,视觉上"看起来归一化"并不代表物理内容完整。
同一网格上的多个态:QFunc
当需要在同一套坐标网格上计算多个态时,应使用类接口:
from qutip import QFunc q_on_grid = QFunc(xvec, yvec, memory=256) Q_first = q_on_grid(state_a) Q_second = q_on_grid(state_b)QFunc在构造时固定坐标,然后用每个态直接调用该对象。需要注意两点:
- QuTiP 5.3 的
QFunc没有.eval方法——不要按旧习惯寻找.eval(...)调用,直接q_on_grid(state)即可; memory参数以 MB 为单位约束内部工作区大小,大态可能触发MemoryError。对于一次性计算单个大态,更稳妥的做法是用qfunc并仔细挑选precompute_memory参数。
仓库 SKILL.md 中展示了稳态场景下两者的等价用法并断言Q_once.shape == (len(xvec), len(xvec)),同时明确本技能不使用 Python 动态代码执行(不构造、编译任何字符串表达式),与QFunc无.eval的现状一致。
Bloch 球:静态态矢与动力学轨迹
静态布洛赫矢量
import matplotlib.pyplot as plt from qutip import Bloch, basis psi = (basis(2, 0) + 1j * basis(2, 1)).unit() # 处于叠加态的单个量子比特 bloch = Bloch() bloch.add_states(psi) bloch.add_vectors([0.0, 0.0, 1.0], color="black") bloch.make_sphere() plt.show()动力学:三个泡利期望值驱动轨迹
对于含时演化,用mesolve保存三个泡利期望值,再逐点绘制:
from qutip import sigmax, sigmay, sigmaz result = mesolve( H, rho0, tlist, c_ops=c_ops, e_ops=[sigmax(), sigmay(), sigmaz()], ) bloch = Bloch() bloch.add_points([result.expect[0], result.expect[1], result.expect[2]]) bloch.make_sphere()也可以保存完整态序列(store_states=True)后add_states,但前者更省内存,且期望值序列同时便于做定量审计。e_ops的字典形式会给出命名良好的result.e_data(见 time_evolution.md 的结果语义表),适合直接送入绘图。
布洛赫矢量审计
- 逐一审计每个布洛赫矢量范数:密度矩阵映射到单位球内部(纯态在球面、混合态在球内);若矢量显著落在球外(范数明显大于 1),表明存在数值误差或建模错误(例如非物理的退相干率、未做 secular 化导致的非正定性,参见 analysis.md);
- 使用显式颜色与线型、采用色盲安全配色:
import qutip qutip.settings.colorblind_safe = True不过要注意:在可复用的库代码中避免随意改动全局设置,除非调用方明确期望该行为——全局设置污染会让不同模块的图风格互相干扰。
Fock 分布:plot_fock_distribution
from qutip import plot_fock_distribution fig, ax = plot_fock_distribution(state) ax.set(title="Fock probabilities", xlabel="n", ylabel="Probability") fig.tight_layout()多态比较时,共享坐标轴并使用返回的fig, ax:
fig, axes = plt.subplots(1, 2, figsize=(9, 3), sharey=True) plot_fock_distribution(state_a, fig=fig, ax=axes[0]) plot_fock_distribution(state_b, fig=fig, ax=axes[1])重要提示:报告中应给出最高被占据能级的概率。即使最后一个柱子在视觉上很小,如果目标观测量对高占据数加权强烈(例如量子非线性的高阶过程),这个尾部概率仍然可能是不可忽略的——"看不见"不等于"不相关"。这与仓库 core_concepts.md 中"检查截断附近占据数"的要求一脉相承。
矩阵诊断:Hinton 图与三维矩阵直方图
密度矩阵(或一般算符)的结构诊断有两种 QuTiP 5 原生工具:
from qutip import hinton fig, ax = hinton(rho, color_style="phase")from qutip import matrix_histogram fig, ax = matrix_histogram(rho, bar_style="abs", color_style="phase")QuTiP 5 的参数命名已更新:使用x_basis、y_basis、bar_style、color_style,而不再是旧版随意的标签与柱型配方。凡是函数支持传Qobj的地方都应传入Qobj,以便保留维度感知的标签(复合系统各子系统的张量积顺序直接反映在标签中,见 core_concepts.md 的dims约定)。
实用建议:
- 对中等规模以上的稠密矩阵,热力图通常比三维柱状图更易读、开销更低(
matrix_histogram的 3D 渲染在元素数增加时很快变得昂贵); - 当虚部相关时绝不隐藏虚部——例如耗散动力学中相干项(非对角元)的虚部携带物理信息,只画
abs会丢失相位结构。
求解器结果绘图:plot_expect与显式绘图
QuTiP 5.3 为求解器结果新增了便捷绘图方法:
fig, axes = result.plot_expect(labels=["population", "coherence"])对于发表级图表或可复用分析代码,显式绘图仍然更清晰、更可控:
fig, ax = plt.subplots() ax.plot(result.times, result.e_data["population"], label="population") ax.set(xlabel="time", ylabel="expectation value") ax.legend() fig.tight_layout()result.e_data仅在e_ops以字典形式传入时存在;列表形式则对应result.expect。详见 time_evolution.md 的结果属性表(times、states、final_state、expect、e_data、options、solver、stats)。
多轨迹均值必须带不确定度带
对mcsolve/ssesolve/smesolve等多轨迹结果,只画均值会掩盖采样误差:
mean = np.asarray(result.expect[0]) standard_error = np.asarray(result.std_expect[0]) / np.sqrt(result.num_trajectories) ax.plot(result.times, mean) ax.fill_between( result.times, mean - 1.96 * standard_error, mean + 1.96 * standard_error, alpha=0.25, )务必确认轨迹估计器设计与样本数能支撑你选用的区间公式:上述std / sqrt(ntraj)只是简单独立样本近似。正如 analysis.md 所指出的,std_expect是轨迹间散布,并不自动等于均值标准误;对重尾、相关或混合初始态采样,应审查采样设计后再决定误差条公式。报告还应注明实际运行的轨迹数(target_tol可能提前停止)、result.seeds与求解器统计信息。
相关函数与频谱绘图:复数要分开画
复数相关函数
两时相关函数通常是复数,应刻意地分开绘制实部与虚部:
fig, axes = plt.subplots(2, 1, sharex=True) axes[0].plot(taulist, np.real(correlation), label="real") axes[1].plot(taulist, np.imag(correlation), label="imaginary") axes[1].set_xlabel("delay") for ax in axes: ax.legend()相关函数的具体计算入口(correlation_2op_1t、correlation_2op_2t及三算符接口)与算符顺序约定、state0=None的含义、max_t_plus_tau参数等,见 analysis.md;请勿从变量名推断算符顺序。
频谱图的纪律
- 标注角频率及其单位(QuTiP 约定 (\hbar=1),角频率与时间互为倒数单位,循环频率需乘 (2\pi),见 core_concepts.md);
- 物理上有意义时显示负频率(例如热库的精细平衡);
- 披露加窗、平滑与零填充等处理;
- 值可能为负时避免对数纵轴;
- 图注中给出频率分辨率与收敛信息。
spectrum是稳态谱,若用有限窗口相关函数的 FFT 逼近谱,还需逐一核对尾部衰减、时间步混叠、频率分辨率、窗函数敏感性与变换约定(仓库的steady_state_spectrum_planner.py将以上检查固化为可直接执行的验收计划,见下文)。
动画:先静态帧,后动画
动画容易掩盖不收敛问题,且渲染成本高。首先在物理上有意义的时刻输出静态帧;确实需要动画时遵守以下纪律:
- 限制帧数与分辨率;
- 保持各帧的相空间色标范围固定(否则颜色对比会误导视觉判断);
- 不要在帧回调里重复计算求解器动力学(应预先算好状态序列再播放);
- 保存到用户明确选择的本地路径;
- 记录时间到帧的映射(每帧对应哪个
t)。
QuTiP 5 在可视化 API 中包含动画辅助工具,但其输入仍要求先保存状态并做好内存规划(例如mesolve的store_states会显著增加内存占用,轨迹求解的keep_runs_results内存随轨迹数×时间点数增长,见 time_evolution.md)。
图表导出:让图成为可复现结果的一部分
fig.savefig("phase_space.svg", bbox_inches="tight") fig.savefig("phase_space.png", dpi=300, bbox_inches="tight")- 使用显式的本地输出路径;
- 未经用户意图确认不要覆盖已有文件;
- 在图表旁边保存数值数据与配置(网格、参数、版本、种子)——栅格图像本身不是可复现的结果。
仓库配套的 result_audit.py 只接受有界的严格 JSON 报告,检查版本、有限值、单调时间网格、布居数界、解析参考误差与收敛差异,且不会反序列化 Python 对象(避免执行不可信代码);可视化工作流应同样遵循"图 + 数值摘要 + 配置"三件套的导出习惯。
配套审计工具链:画图之前先过数值关
本仓库的 QuTiP 技能提供了一组本地、无网络的 CLI 工具(详见 SKILL.md),与可视化配合构成完整工作流:
| 脚本 | 与可视化的关系 |
|---|---|
| scripts/steady_state_spectrum_planner.py | 为稳态与谱图预生成验收计划:检查稳态唯一性、算符顺序、频率正负约定、Nyquist 上限、谱分辨率,并输出warnings/blockers |
| scripts/result_audit.py | 审计导出的数值报告(严格 JSON),确保图表背后的数据可信 |
| scripts/convergence_sweep.py | 扫描截断/容差/轨迹数,为"图是否收敛"提供定量证据 |
| scripts/two_level_simulation.py | 生成可复现的两能级模拟数据,作为绘图的输入源 |
例如,steady_state_spectrum_planner.py会基于--tau-max、--tau-points计算 FFT 的 Nyquist 角频率与近似频率分辨率,并在请求的频率范围超限时给出警告——这直接对应上文"频谱图要标注频率分辨率与收敛信息"的要求:
python skills/qutip/scripts/steady_state_spectrum_planner.py \ --spectrum-mode both --tau-max 50 --tau-points 2001 \ --frequency-min -5 --frequency-max 5 --stationary-confirmed这些脚本的模拟导入都是惰性的(--help不需要安装 QuTiP),且所有 I/O 都有界并拒绝 URL/符号链接,符合可复现、可审计的科研软件实践。
可视化自检清单(收尾)
- 确认
qutip==5.3.0与qutip[graphics]已安装、版本已锁定; wigner/qfunc/QFunc的返回值形状为(len(yvec), len(xvec)),xvec水平、yvec竖直传给pcolormesh;- 使用非对称的 x/y 网格做过一次轴顺序冒烟测试;
- Wigner 图扫描过截断维数、相空间范围与网格密度,并区分数值容差负值与稳健负性;
QFunc按"构造时固定坐标 + 调用时传态"使用,未使用不存在的.eval,并监控memory上限;- 布洛赫矢量逐点审计范数,混合态矢量未漂出单位球;
- Fock 分布报告最高占据能级概率;
- 多轨迹均值附带经论证的不确定度带;
- 频谱图标注角频率/单位、负频率与加窗等处理;
- 动画帧色标固定、静态帧先行;
- 图与数值数据、配置、版本、种子一同导出保存。
深入仓库继续学习
- 可视化参考文档:本文的原始依据,含 API 签名与全部示例;
- SKILL.md:技能总览、环境快照、模型契约与求解器选型表;
- core_concepts.md:Qobj、维度、张量积顺序、态物理性与截断审计;
- time_evolution.md:求解器签名、选项字典、结果语义与多轨迹统计;
- analysis.md:稳态、相关函数、频谱与收敛矩阵的完整检查清单;
- scripts/steady_state_spectrum_planner.py:谱图验收计划的 CLI 实现。
【免费下载链接】scientific-agent-skillsTurn any AI agent into an AI Scientist. The #1 Agent Skills library for science, used by 190,000+ scientists worldwide. 165 ready-to-use validated skills plus 100+ scientific databases covering biology, chemistry, medicine, and drug discovery. Compatible with Cursor, Claude Code, Codex, Pi, Antigravity, and the open Agent Skills standard.项目地址: https://gitcode.com/GitHub_Trending/cl/scientific-agent-skills
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考