viz: improve x-axis readability with ConciseDateFormatter, fewer ticks, and wider figure
All checks were successful
Generate banlist history graph / build (push) Successful in 7s
All checks were successful
Generate banlist history graph / build (push) Successful in 7s
This commit is contained in:
parent
7d8cd95c07
commit
98c4fc3c19
1 changed files with 25 additions and 10 deletions
|
@ -93,6 +93,7 @@ def write_chart(snaps: List[Snapshot], image_path: str) -> None:
|
||||||
import matplotlib
|
import matplotlib
|
||||||
matplotlib.use("Agg") # headless
|
matplotlib.use("Agg") # headless
|
||||||
import matplotlib.pyplot as plt
|
import matplotlib.pyplot as plt
|
||||||
|
import matplotlib.dates as mdates
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"Skipping chart generation (matplotlib unavailable): {e}")
|
print(f"Skipping chart generation (matplotlib unavailable): {e}")
|
||||||
return
|
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]
|
xs = [datetime.fromtimestamp(s.timestamp, tz=timezone.utc) for s in snaps]
|
||||||
ys = [s.count for s in snaps]
|
ys = [s.count for s in snaps]
|
||||||
|
|
||||||
plt.figure(figsize=(8, 3))
|
fig, ax = plt.subplots(figsize=(9.5, 3.2))
|
||||||
plt.plot(xs, ys, marker="o", linewidth=1.5, markersize=2)
|
ax.plot(xs, ys, marker="o", linewidth=1.5, markersize=2)
|
||||||
plt.title("WageNet IP Ban List Size Over Time")
|
ax.set_title("WageNet IP Ban List Size Over Time")
|
||||||
plt.xlabel("Date (UTC)")
|
ax.set_xlabel("Date (UTC)")
|
||||||
plt.ylabel("IP count")
|
ax.set_ylabel("IP count")
|
||||||
plt.grid(True, linestyle=":", linewidth=0.5)
|
ax.grid(True, linestyle=":", linewidth=0.5)
|
||||||
plt.tight_layout()
|
|
||||||
|
# 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)
|
os.makedirs(os.path.dirname(image_path), exist_ok=True)
|
||||||
plt.savefig(image_path)
|
fig.savefig(image_path)
|
||||||
plt.close()
|
plt.close(fig)
|
||||||
|
|
||||||
|
|
||||||
def main() -> int:
|
def main() -> int:
|
||||||
|
@ -146,4 +162,3 @@ def main() -> int:
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
raise SystemExit(main())
|
raise SystemExit(main())
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue