Download app.py from HugBot/Widget: direct link, hf CLI and curl.
- Browser
- Download file 6.3 kB
-
https://huggingface.co/spaces/HugBot/Widget/resolve/main/app.py
- Command line
-
hf download hf://spaces/HugBot/Widget/app.py
-
curl -L -o app.py https://huggingface.co/spaces/HugBot/Widget/resolve/main/app.py
6.3 kB
| import numpy as np | |
| import matplotlib.pyplot as plt | |
| import gradio as gr | |
| # ββ style ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| BG = '#f8fafc' | |
| PANEL = '#ffffff' | |
| GRID = '#e2e8f0' | |
| ACCENT = '#2563eb' | |
| C_INC = '#d97706' | |
| C_ZS = '#7c3aed' | |
| C_RR = '#059669' | |
| C_TEXT = '#1e293b' | |
| C_DIM = '#64748b' | |
| C_BORDER = '#cbd5e1' | |
| plt.rcParams.update({ | |
| 'figure.facecolor': BG, 'axes.facecolor': PANEL, | |
| 'axes.edgecolor': C_BORDER, 'axes.labelcolor': C_DIM, | |
| 'xtick.color': C_DIM, 'ytick.color': C_DIM, | |
| 'grid.color': GRID, 'grid.linewidth': 0.8, | |
| 'text.color': C_TEXT, 'font.family': 'monospace', | |
| }) | |
| EP_RANGE = np.linspace(0, 15, 600) | |
| def calc_paf(episodes, incidence, zscore, rr): | |
| return 1 - 1 / np.exp(episodes * incidence * zscore * rr) | |
| # ββ plot function ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| def draw(ep, inc, zs, rr): | |
| paf_curve = calc_paf(EP_RANGE, inc, zs, rr) * 100 | |
| cur_paf = calc_paf(ep, inc, zs, rr) | |
| exponent = ep * inc * zs * rr | |
| fig, axes = plt.subplots(1, 2, figsize=(15, 6), | |
| gridspec_kw={'width_ratios': [3, 1]}) | |
| fig.patch.set_facecolor(BG) | |
| # ββ left: curve βββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| ax = axes[0] | |
| ax.set_facecolor(PANEL) | |
| for spine in ax.spines.values(): | |
| spine.set_color(C_BORDER) | |
| # shadow + main curve | |
| ax.plot(EP_RANGE, paf_curve, color=ACCENT, linewidth=5, alpha=0.15) | |
| ax.plot(EP_RANGE, paf_curve, color=ACCENT, linewidth=2.2) | |
| # crosshairs | |
| ax.axvline(ep, color=ACCENT, linestyle='--', linewidth=1.2, alpha=0.6) | |
| ax.axhline(cur_paf*100, color=ACCENT, linestyle='--', linewidth=1.2, alpha=0.3) | |
| # dot at current point | |
| ax.scatter([ep], [cur_paf*100], color=ACCENT, s=80, zorder=5, | |
| edgecolors='white', linewidths=1.5) | |
| # shaded area under curve up to current episode | |
| mask = EP_RANGE <= ep | |
| ax.fill_between(EP_RANGE[mask], paf_curve[mask], color=ACCENT, alpha=0.08) | |
| ax.set_xlim(0, 15) | |
| ax.set_ylim(0, 102) | |
| ax.set_xlabel('Episodes', fontsize=11, labelpad=8) | |
| ax.set_ylabel('PAF (%)', fontsize=11, labelpad=8) | |
| ax.set_title('Population Attributable Fraction', | |
| color=C_TEXT, fontsize=13, pad=12, fontweight='normal') | |
| ax.grid(True, linewidth=0.8) | |
| # annotation | |
| ax.annotate( | |
| f' {cur_paf*100:.1f}%', | |
| xy=(ep, cur_paf*100), | |
| xytext=(min(ep + 1, 13), cur_paf*100 + 4), | |
| color=ACCENT, fontsize=15, fontweight='bold', | |
| arrowprops=dict(arrowstyle='->', color=ACCENT, lw=1.2) | |
| ) | |
| # formula watermark | |
| ax.text(0.98, 0.05, | |
| 'PAF = 1 β exp(βep Γ inc Γ Ξz Γ RR)', | |
| transform=ax.transAxes, fontsize=11, | |
| color=C_DIM, ha='right', va='bottom') | |
| # ββ right: breakdown panel ββββββββββββββββββββββββββββββββββββββββββββ | |
| ax2 = axes[1] | |
| ax2.set_facecolor('#f1f5f9') | |
| for spine in ax2.spines.values(): | |
| spine.set_color(C_BORDER) | |
| ax2.set_xticks([]) | |
| ax2.set_yticks([]) | |
| rows = [ | |
| ('episodes', f'{ep:.2f}', ACCENT), | |
| ('incidence', f'{inc:.3f}', C_INC), | |
| ('Ξz / ep.', f'{zs:.3f}', C_ZS), | |
| ('RR', f'{rr:.3f}', C_RR), | |
| ('β' * 10, 'β' * 6, C_BORDER), | |
| ('exponent', f'{exponent:.4f}', '#475569'), | |
| ('exp(βx)', f'{1/np.exp(exponent):.4f}', '#475569'), | |
| ('β' * 10, 'β' * 6, C_BORDER), | |
| ('PAF', f'{cur_paf*100:.2f}%', ACCENT), | |
| ] | |
| ax2.text(0.5, 0.97, 'BREAKDOWN', transform=ax2.transAxes, | |
| ha='center', fontsize=13, color=ACCENT, fontweight='bold') | |
| y_start = 0.88 | |
| for i, (k, v, c) in enumerate(rows): | |
| y = y_start - i * 0.095 | |
| ax2.text(0.08, y, k, transform=ax2.transAxes, | |
| fontsize=11, color=C_DIM, va='center') | |
| ax2.text(0.92, y, v, transform=ax2.transAxes, | |
| fontsize=11, color=c, va='center', ha='right', fontweight='bold') | |
| ax2.set_title('Parameters', color=C_TEXT, fontsize=13, pad=8) | |
| plt.tight_layout(pad=1.5) | |
| return fig | |
| # ββ Gradio UI βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| with gr.Blocks(theme=gr.themes.Soft(), title="PAF Visualizer") as demo: | |
| gr.HTML(""" | |
| <div style="background:#eff6ff;border:1px solid #bfdbfe;border-radius:10px; | |
| padding:12px 20px;margin-bottom:12px;font-family:monospace;"> | |
| <span style="color:#1e293b;font-size:20px;font-weight:600;"> | |
| Population Attributable Fraction Visualizer | |
| </span><br> | |
| <span style="color:#64748b;font-size:13px;"> | |
| PAF = 1 β exp(βepisodes Γ incidence Γ Ξz Γ RR) | |
| </span> | |
| </div>""") | |
| with gr.Row(): | |
| with gr.Column(): | |
| ep = gr.Slider(0, 10, value=4.2, step=0.1, label="Episodes") | |
| inc = gr.Slider(0.01, 1, value=0.2, step=0.01, label="Pathogen Incidence") | |
| zs = gr.Slider(0.01, 1, value=0.2, step=0.01, label="Ξz per Episode") | |
| rr = gr.Slider(1.01, 3, value=1.5, step=0.05, label="Relative Risk (RR)") | |
| reset_btn = gr.Button("Reset Defaults", variant="secondary") | |
| plot = gr.Plot(label="") | |
| # live update on any slider change | |
| for slider in [ep, inc, zs, rr]: | |
| slider.change(fn=draw, inputs=[ep, inc, zs, rr], outputs=plot) | |
| # reset button | |
| def reset(): | |
| return 5.0, 0.3, 1.2, 2.5 | |
| reset_btn.click(fn=reset, outputs=[ep, inc, zs, rr]) | |
| # draw on load | |
| demo.load(fn=draw, inputs=[ep, inc, zs, rr], outputs=plot) | |
| demo.launch() |