cove-scripts/activity_graph.py
2025-03-01 04:24:17 +01:00

101 lines
2.6 KiB
Python

import argparse
import datetime
import json
from collections import Counter
from pathlib import Path
import matplotlib.dates as mdates
import matplotlib.pyplot as plt
import pandas as pd
class Data:
def __init__(self):
self.by_day = Counter()
def add_msg(self, msg):
dt = datetime.datetime.fromtimestamp(msg["time"], tz=datetime.UTC)
self.by_day[dt.date()] += 1
def main():
parser = argparse.ArgumentParser()
parser.add_argument("json_logs", type=Path, nargs="+")
args = parser.parse_args()
data = Data()
for path in args.json_logs:
print(f"Reading {path}")
n = 0
with open(path) as f:
for line in f:
data.add_msg(json.loads(line))
n += 1
if n % 100000 == 0:
print(f"{n:10}")
print(f"{n:10}")
first_day = min(data.by_day.keys())
last_day = max(data.by_day.keys())
print(f"Got logs from {first_day} to {last_day}")
# The following code was generated by ChatGPT and adjusted by me
# Extract sorted dates and counts
dates = sorted(data.by_day.keys())
counts = [data.by_day[date] for date in dates]
# Convert to DataFrame for moving average calculation
df = pd.DataFrame({"date": dates, "count": counts})
df.set_index("date", inplace=True)
df = df.asfreq("D", fill_value=0) # Fill missing dates with 0
avg = df["count"].rolling(
window=30,
min_periods=1,
center=True,
win_type="gaussian",
)
df["30_day_avg"] = avg.mean(std=8)
# Create the plot
fig, ax = plt.subplots(figsize=(10, 5))
ax.plot(
df.index,
df["count"],
linestyle="-",
linewidth=0.5,
color="#348ceb",
label="Messages",
)
ax.plot(
df.index,
df["30_day_avg"],
linestyle="-",
linewidth=0.5,
color="#a80303",
label="30-day moving average",
)
# Format x-axis for better readability
ax.xaxis.set_major_locator(mdates.YearLocator()) # Major ticks per year
ax.xaxis.set_minor_locator(mdates.MonthLocator()) # Minor ticks per month
ax.xaxis.set_major_formatter(mdates.DateFormatter("%Y")) # Year labels
ax.set_xlabel("Time")
ax.set_ylabel("Messages")
ax.set_ylim(0) # Start y-axis at 0
ax.set_title("Activity Graph™")
ax.legend()
ax.grid(True, which="both", linestyle="--", linewidth=0.5)
# Rotate x-axis labels for clarity
plt.xticks(rotation=45)
plt.tight_layout()
# Save the plot to a PNG file
plt.savefig("activity_graph.png", dpi=300)
plt.close()
if __name__ == "__main__":
main()