"""ex05persimvisualize.py — 第 5 章 persim 可视化与瓶颈距离 对应教程:tutorials/05-visualization.md。 演示: plotdiagrams:多维持久图同图 plotbars:条形码视图 PersistenceImager:持久图像(向量化) bottleneck:两持久图的瓶颈距离 运行: python ex05persimvisualize.py """ import numpy as np from ripser import ripser from persim import plotdiagrams, plotbars import matplotlib.
"""ex05_persim_visualize.py — 第 5 章 persim 可视化与瓶颈距离
对应教程:tutorials/05-visualization.md。
演示:
运行:
python ex05_persim_visualize.py
"""
import numpy as np
from ripser import ripser
from persim import plot_diagrams, plot_bars
import matplotlib.pyplot as plt
from common import sample_circle, top_features
def main():
data = sample_circle(n=120, noise=0.05, seed=7)
dgms = ripser(data, maxdim=1)['dgms']
# ── 1. 持久图 + 条形码 ── fig, axes = plt.subplots(1, 2, figsize=(12, 4.5)) plot_diagrams(dgms, ax=axes[0], labels=['H0', 'H1'], show=False) axes[0].set_title('持久图(Persistence Diagram)') # H1 条形码:每条水平线段 = 一个特征的 [birth, death] plot_bars(dgms[1], ax=axes[1]) axes[1].set_title('H1 条形码(Barcode)') plt.tight_layout() # ── 2. top_features:手动找最显著特征 ── top, pers = top_features(dgms[1], k=3) print("=== H1 最显著的 3 个特征 ===") for row, p in zip(top, pers): death = row[1] if np.isfinite(row[1]) else float('inf') print(f" birth={row[0]:.3f} death={death:.3f} " f"persistence={p:.3f}") # ── 3. 瓶颈距离:同一圆环两次独立采样的 H1 ── from persim import bottleneck data2 = sample_circle(n=120, noise=0.05, seed=99) dgm2 = ripser(data2, maxdim=1)['dgms'][1] dist, _ = bottleneck(dgms[1], dgm2) print(f"\n两次独立采样 H1 瓶颈距离 = {dist:.4f}(应较小)") plt.show()
if name == "main":
main()