diff --git a/scripts/banlist_metrics.py b/scripts/banlist_metrics.py index 25fe41b..9ca86c1 100644 --- a/scripts/banlist_metrics.py +++ b/scripts/banlist_metrics.py @@ -93,6 +93,7 @@ def write_chart(snaps: List[Snapshot], image_path: str) -> None: import matplotlib matplotlib.use("Agg") # headless import matplotlib.pyplot as plt + import matplotlib.dates as mdates except Exception as e: print(f"Skipping chart generation (matplotlib unavailable): {e}") return @@ -104,17 +105,32 @@ def write_chart(snaps: List[Snapshot], image_path: str) -> None: xs = [datetime.fromtimestamp(s.timestamp, tz=timezone.utc) for s in snaps] ys = [s.count for s in snaps] - plt.figure(figsize=(8, 3)) - plt.plot(xs, ys, marker="o", linewidth=1.5, markersize=2) - plt.title("WageNet IP Ban List Size Over Time") - plt.xlabel("Date (UTC)") - plt.ylabel("IP count") - plt.grid(True, linestyle=":", linewidth=0.5) - plt.tight_layout() + fig, ax = plt.subplots(figsize=(9.5, 3.2)) + ax.plot(xs, ys, marker="o", linewidth=1.5, markersize=2) + ax.set_title("WageNet IP Ban List Size Over Time") + ax.set_xlabel("Date (UTC)") + ax.set_ylabel("IP count") + ax.grid(True, linestyle=":", linewidth=0.5) + + # Reduce x-axis label crowding + try: + locator = mdates.AutoDateLocator(minticks=4, maxticks=8) + formatter = mdates.ConciseDateFormatter(locator) + ax.xaxis.set_major_locator(locator) + ax.xaxis.set_major_formatter(formatter) + except Exception: + # Fallback: rotate labels if ConciseDateFormatter isn't available + for label in ax.get_xticklabels(): + label.set_rotation(30) + label.set_horizontalalignment("right") + + # Add slight horizontal margins to prevent clipping at edges + ax.margins(x=0.02) + fig.tight_layout() os.makedirs(os.path.dirname(image_path), exist_ok=True) - plt.savefig(image_path) - plt.close() + fig.savefig(image_path) + plt.close(fig) def main() -> int: @@ -146,4 +162,3 @@ def main() -> int: if __name__ == "__main__": raise SystemExit(main()) -