| import matplotlib.pyplot as plt |
| from typing import Dict, List, Tuple |
|
|
|
|
| def plot_telemetry( |
| metrics_log: Dict[str, List[float]], |
| k_floor: float = 0.5, |
| c_floor: float = 0.3, |
| s_floor: float = 0.5, |
| ) -> Tuple[plt.Figure, List[plt.Axes]]: |
| """Plot K, C, S metrics over time with cluster transitions. |
| |
| Args: |
| metrics_log: Dictionary with keys ``negentropy``, ``lz_complexity``, |
| ``symbiosis_score`` and optional ``clusters`` listing cluster |
| assignments per step. |
| k_floor: Threshold for negentropy (K). |
| c_floor: Threshold for LZ complexity (C). |
| s_floor: Threshold for symbiosis score (S). |
| |
| Returns: |
| (figure, axes) tuple for further customization or saving. |
| """ |
| steps = list(range(len(metrics_log.get("negentropy", [])))) |
| fig, axes = plt.subplots(3, 1, sharex=True, figsize=(10, 6)) |
| metrics = [ |
| ("negentropy", k_floor, "K"), |
| ("lz_complexity", c_floor, "C"), |
| ("symbiosis_score", s_floor, "S"), |
| ] |
| for ax, (key, floor, label) in zip(axes, metrics): |
| values = metrics_log.get(key, []) |
| ax.plot(steps, values, label=label) |
| ax.axhline(floor, color="r", linestyle="--", linewidth=1) |
| violations = [i for i, v in enumerate(values) if v < floor] |
| if violations: |
| ax.scatter( |
| [steps[i] for i in violations], |
| [values[i] for i in violations], |
| color="r", |
| zorder=5, |
| label="violation", |
| ) |
| ax.set_ylabel(label) |
| ax.legend(loc="upper right") |
|
|
| clusters = metrics_log.get("clusters") |
| if clusters is not None: |
| prev = clusters[0] |
| for t, c in enumerate(clusters): |
| if t > 0 and c != prev: |
| for ax in axes: |
| ax.axvline(t, color="gray", linestyle=":", alpha=0.5) |
| prev = c |
|
|
| axes[-1].set_xlabel("step") |
| plt.tight_layout() |
| return fig, axes |
|
|