typestar

mpl_dashboard.py in Python

A four-panel dashboard built from one dataset, saved as a single figure.

import matplotlib

matplotlib.use("Agg")
import matplotlib.pyplot as plt
import numpy as np

ACCENT = "#7c5cff"
WARM = "#e06c75"


def make_runs(days=60, seed=3):
    """Simulated practice history: improving, with noise."""
    rng = np.random.default_rng(seed)
    trend = np.linspace(78, 112, days)
    tpm = trend + rng.normal(scale=4.5, size=days)
    accuracy = 94 + (tpm - tpm.min()) / (np.ptp(tpm) + 1e-9) * 5
    langs = rng.choice(["python", "rust", "sql", "css"], size=days,
                       p=[0.45, 0.25, 0.2, 0.1])
    return tpm, accuracy, langs


def panel_progress(axes, tpm):
    x = np.arange(len(tpm))
    axes.plot(x, tpm, color=ACCENT, linewidth=1, alpha=0.6)
    window = 7
    smooth = np.convolve(tpm, np.ones(window) / window, mode="valid")
    axes.plot(x[window - 1:], smooth, color=WARM, linewidth=2,
              label=f"{window}-run average")
    axes.set_title("tokens per minute", fontsize=10)
    axes.legend(fontsize=8)


def panel_distribution(axes, tpm):
    axes.hist(tpm, bins=18, color=ACCENT, edgecolor="white")
    axes.axvline(np.median(tpm), color=WARM, linestyle="--",
                 label=f"median {np.median(tpm):.0f}")
    axes.set_title("distribution", fontsize=10)
    axes.legend(fontsize=8)


def panel_languages(axes, langs):
    names, counts = np.unique(langs, return_counts=True)
    order = np.argsort(counts)[::-1]
    bars = axes.barh(names[order][::-1], counts[order][::-1], color=ACCENT)
    axes.bar_label(bars, padding=2, fontsize=8)
    axes.set_title("runs per language", fontsize=10)
    axes.set_xlim(0, counts.max() * 1.2)


def panel_tradeoff(axes, tpm, accuracy):
    points = axes.scatter(tpm, accuracy, c=np.arange(len(tpm)),
                          cmap="viridis", s=16)
    fit = np.polyfit(tpm, accuracy, 1)
    axes.plot(tpm, np.polyval(fit, tpm), color=WARM, linewidth=1.5)
    axes.set_xlabel("tpm", fontsize=9)
    axes.set_ylabel("accuracy %", fontsize=9)
    axes.set_title("speed against accuracy", fontsize=10)
    return points


def main():
    tpm, accuracy, langs = make_runs()

    figure, axes = plt.subplots(2, 2, figsize=(10, 6.5))
    panel_progress(axes[0, 0], tpm)
    panel_distribution(axes[0, 1], tpm)
    panel_languages(axes[1, 0], langs)
    points = panel_tradeoff(axes[1, 1], tpm, accuracy)

    figure.colorbar(points, ax=axes[1, 1], label="run order")
    figure.suptitle("practice dashboard", fontsize=13)
    figure.tight_layout()
    figure.savefig("dashboard.png", dpi=150, bbox_inches="tight")
    plt.close(figure)

    print(f"{len(tpm)} runs, best {tpm.max():.1f} tpm")
    print(f"improvement {tpm[-7:].mean() - tpm[:7].mean():+.1f} tpm")


if __name__ == "__main__":
    main()

How it works

  1. A gridspec-shaped subplot grid holds panels of different kinds.
  2. Each panel is a small function, so the layout stays readable.
  3. One savefig at the end writes the whole dashboard.

Keywords and builtins used here

The run, in numbers

Lines
81
Characters to type
2441
Tokens
789
Three-star pace
115 tpm

At the three-star pace of 115 tokens a minute, this run takes about 412 seconds.

Type this snippet

Step 1 of 1 in Encore, step 14 of 14 in Plotting with matplotlib.

← Previous