diff --git a/scripts/usage_stats.py b/scripts/usage_stats.py index c42db79..4ffc8c3 100644 --- a/scripts/usage_stats.py +++ b/scripts/usage_stats.py @@ -174,9 +174,7 @@ def _style_ax(ax: plt.Axes) -> None: def make_figure(df: pd.DataFrame, output: Path) -> None: # ── daily logins ────────────────────────────────────────────────────────── login_mask = (df["method"] == "POST") & (df["path"] == "/api/auth/login") & (df["status"] == 200) - full_range = pd.date_range(df["ts"].min(), df["ts"].max(), freq="D", tz="UTC") - daily_logins = df[login_mask].set_index("ts").resample("D").size().reindex(full_range, fill_value=0) - rolling7 = daily_logins.rolling(7, center=True, min_periods=1).mean() + weekly_logins = df[login_mask].set_index("ts").resample("W-MON").size() # ── feature usage (weekly) ──────────────────────────────────────────────── feat_df = df[df["feature"].notna()].copy() @@ -212,16 +210,18 @@ def make_figure(df: pd.DataFrame, output: Path) -> None: for ax in (ax_log, ax_heat, ax_feat): _style_ax(ax) - # Panel 1 — daily logins + rolling mean - ax_log.bar(daily_logins.index, daily_logins.values, - color=BLUE, alpha=0.30, width=pd.Timedelta(hours=20)) - ax_log.plot(daily_logins.index, rolling7.values, - color=BLUE, linewidth=2, label="7-day avg") - ax_log.set_title("Daily logins", color=FG, fontsize=11, pad=8) + # Panel 1 — weekly logins + n_w = len(weekly_logins) + week_x = np.arange(n_w) + ax_log.bar(week_x, weekly_logins.values, color=BLUE, alpha=0.70, width=0.6) + ax_log.set_xticks(week_x) + ax_log.set_xticklabels( + [str(w.date()) for w in weekly_logins.index], + rotation=30, ha="right", fontsize=8, color=FG, + ) + ax_log.set_title("Weekly logins", color=FG, fontsize=11, pad=8) ax_log.set_ylabel("count", color=FG, fontsize=9) ax_log.yaxis.set_major_locator(ticker.MaxNLocator(integer=True, nbins=5)) - ax_log.tick_params(axis="x", rotation=25) - ax_log.legend(fontsize=8, framealpha=0.15, facecolor=BG, edgecolor=GRID) ax_log.grid(axis="y", color=GRID, linewidth=0.5) # Panel 2 — heatmap @@ -262,7 +262,7 @@ def make_figure(df: pd.DataFrame, output: Path) -> None: ax_feat.text(0.5, 0.5, "No feature data (no Referer headers yet)", ha="center", va="center", color=FG, transform=ax_feat.transAxes) - total_logins = int(login_mask.sum()) + total_logins = int(weekly_logins.sum()) span_days = (df["ts"].max() - df["ts"].min()).days + 1 fig.suptitle( f"bincio — {total_logins} logins over {span_days} days "