10
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Qiita】今年1年のContributionを集計してグラフ化してみる

Posted at

今年の初めにQiitaを始めてみて、気づけばもう11月。
年末に近づいて、1年のコントリビューションはどんな感じだったのかなと思い、QiitaのAPIを使ってグラフ化してみました。


✅ やること

  • Qiita APIで自分の投稿データを取得
  • 投稿数・いいね数(likes)・ストック数を月ごとに集計
  • 投稿+いいね+ストック = 貢献スコアとして折れ線グラフ化
  • さらに累積グラフも作る

Contributionには色々加算ポイントあるみたいですが、とりあえず投稿数、いいね数、ストック数を集計。


✅ 使った環境

項目 内容
言語 Python 3
ライブラリ requests / pandas / matplotlib
Qiita API 認証トークンなし(公開データのみ)でOK

✅ 実際のコード

import requests
import pandas as pd
import matplotlib.pyplot as plt

# ========= 1. 設定 =========
QIITA_USER_ID = "yushibats"   # QiitaのユーザーID
TOKEN = ""                    # 公開データのみ取得する場合は空でOK

# 表示したい期間(各月の月初基準)
FILTER_START = "2025-01-01"
FILTER_END   = "2025-12-31"

# トークンがあればヘッダーに追加
headers = {"Authorization": f"Bearer {TOKEN}"} if TOKEN else {}

# ========= 2. Qiita APIから記事データ取得 =========
def fetch_items(user_id):
    items = []
    for page in range(1, 11):  # 1〜10ページ分(最大1000件)
        url = f"https://qiita.com/api/v2/users/{user_id}/items?page={page}&per_page=100"
        r = requests.get(url, headers=headers)
        if r.status_code != 200:
            break 
        data = r.json()
        if not data:
            break
        items.extend(data)
    return items


# ========= 3. DataFrameに変換 & 日付整形 =========
def to_dataframe(items):
    df = pd.DataFrame([{
        "created_at": it["created_at"],
        "posts": 1,
        "likes": it["likes_count"],  
        "stocks": it["stocks_count"]
    } for it in items])

    df["date"] = pd.to_datetime(df["created_at"], utc=True).dt.tz_convert(None)
    return df


# ========= 4. 月初ごと(MS)に集計 =========
def aggregate_monthly(df):
    df_month = df.resample("MS", on="date")[["posts", "likes", "stocks"]].sum()
    full_range = pd.date_range(start=FILTER_START, end=FILTER_END, freq="MS")
    df_month = df_month.reindex(full_range, fill_value=0)
    df_month["score"] = df_month["posts"] + df_month["likes"] + df_month["stocks"] * 0.5
    df_month["cumulative"] = df_month["score"].cumsum()
    return df_month


# ========= 5. グラフ描画 =========
def plot_graph(df_month, user_id):
    plt.figure(figsize=(12, 6))

    # 月ごとの投稿・いいね・ストック
    plt.plot(df_month.index, df_month["posts"], marker="o", label="Posts")
    plt.plot(df_month.index, df_month["likes"], marker="o", label="Likes")
    plt.plot(df_month.index, df_month["stocks"], marker="o", label="Stocks")

    # 月次スコアと累積スコア
    plt.plot(df_month.index, df_month["score"], marker="o", linewidth=2.5,
             label="Monthly Score (Posts + Likes + Stocks*0.5)")
    plt.plot(df_month.index, df_month["cumulative"], linestyle="--", linewidth=2.5,
             label="Cumulative Score")

    plt.title(f"Qiita Contribution Trend @{user_id} (Monthly-based Score)")
    plt.xlabel("Month")
    plt.ylabel("Score")
    plt.grid(True)
    plt.legend()
    plt.tight_layout()

    plt.savefig("qiita_contribution_score.png")
    print("✅ グラフを保存しました!: qiita_contribution_score.png")


# ========= 6. 実行 =========
if __name__ == "__main__":
    items = fetch_items(QIITA_USER_ID)
    df = to_dataframe(items)
    df_month = aggregate_monthly(df)
    plot_graph(df_month, QIITA_USER_ID)

✅ 結果

それっぽいグラフができました。
今年もあと2か月!頑張りましょう!

qiita_contribution_score.png

10
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?