コピペでできるサクッとデータ分析。「Googleスプレッドシート × Pythonで“週データ”を自動集計して“月トレンド”の可視化」─ Colab × Plotlyで一瞬グラフ化する方法。 #102
全体レビューがついに1万ビューを超えた。
60日連続投稿を達成した、そのデータをもとにまとめたのが今回の記事や。
この記事を読むと──
スプレッドシートでアクセスデータを管理するだけで、どんな変動が起きていたのかが見えてくる。
ぁ、ちなみにデータの抽出は自動じゃなくて手動やねんけどな(笑)。
コード含んだ記事なんで、長くなってます・・・・。
そして今回のターゲットは、こんな人👇
「週ごとのアクセスデータをスプレッドシートで管理してるけど、
“月ごとの推移”を見たいときに手作業がめんどくさいんよな…」
そんな人のために、Google Colab × Pythonを使って
「月データ→ グラフ化」までを自動でやってくれる仕組みを作った。

1.元にデータを整える
まず、可視化するにしても、分析するにしても──
そもそもデータがなければ始まらない。
今回は、こんな感じのデータをいまだに人力でスプレッドシートに記録している👇

「週」「ビュー」「コメント」「スキ」だけの、超シンプル構成。
正直、毎週コピペして入力してるので、地味に骨が折れる作業やねん……。
いつかはWebスクレイピングとかで自動化したいとは思ってるけど、
まずは今ある“手動データ”を分析できるように整えることから始めた。
今回のシート名は 「サマリー_月」 に設定。
これをもとに、次のステップで Google Colab × Python から読み込んでいく。
2.Colabでデータを読み込む
ここからはいよいよ Google Colab × Python の出番や。
今回は、スプレッドシートの「サマリー_月」シートに入力した週データを、Colabから直接読み込む。
まずは、Googleアカウントの認証からスタート。
2-1.Googleアカウント認証
# @title 2-1.Googleアカウント認証
from google.colab import auth
from google.auth import default
import gspread
# 認証(最初の1回だけポップアップが出る)
auth.authenticate_user()
creds, _ = default()
gc = gspread.authorize(creds)
これで、ColabとGoogle スプレッドシートをつなぐ準備が完了。
初回実行時には「Googleアカウントの許可」を求められるけど、
一度通れば次からはスムーズにアクセスできるようになる。
2-2.スプレッドシートに接続
# 📂 スプレッドシートのURLを指定(自分のURLに置き換え)
SPREADSHEET_URL = "https://docs.google.com/spreadsheets/d/{XXXXXXX}/edit?gid=0#gid=0"
# ▼ 接続
spreadsheet = gc.open_by_url(SPREADSHEET_URL)
print("✅ 接続OK:", spreadsheet.title)✅ 「接続OK」と表示されたら、Colabがスプレッドシートにアクセスできている状態。
このあと、「サマリー_月」シートを読み込んでDataFrame(表データ)に変換していく。
補足メモ
URLの {XXXXXXX} は、自分のスプレッドシートIDに置き換える。
ファイル共有設定は「リンクを知っている全員が閲覧可能」にしておくと、認証エラーが出にくい。
この接続方法は gspread ライブラリを使った定番の構成。
⚠️ 注意
今回の方法は学習用のシンプル設定(認証トークンをColabで扱うだけ)やから、
機密データや個人情報を含むファイルを扱う場合は、
サービスアカウント+JSONキーで安全に接続する方法に切り替えるのがおすすめやで。
このセクションを終えると、
Colab上でスプレッドシートの中身を自由に扱える状態になる。
3. データをDataFrameとして読み込む
ここでようやく、スプレッドシートの「サマリー_月」シートを PythonのDataFrame(表データ) に変換していく。
# @title 2-1. データの読み込み:ビュー数
sheet = spreadsheet.worksheet("サマリー_月") # ワークシート名を指定
rows = sheet.get_all_values()
# 1行目をヘッダーとして DataFrame を作成
df_view_mon = pd.DataFrame(rows[1:], columns=rows[0])
# 余白行の除去(空白行をすべて削除)
df_view_mon = df_view_mon.replace('', pd.NA).dropna(how='all').reset_index(drop=True)
# 数値カラムを数値化(エラー時は NaN に)
for col in ["ビュー", "コメント", "スキ"]:
df_view_mon[col] = pd.to_numeric(df_view_mon[col], errors="coerce")
# 内容を確認
display(df_view_mon.head())
print("✅ 作成したデータフレーム:df_view_mon")
解説
sheet.get_all_values():スプレッドシート全体をリスト形式で取得。
DataFrame(rows[1:], columns=rows[0]):1行目をヘッダーとしてDataFrameを生成。
replace('', pd.NA) → dropna(how='all'):空白行を削除。
pd.to_numeric():ビュー数・コメント数・スキ数を数値として扱えるように変換。
✅ ここまで実行すれば、Colab上で「週」「ビュー」「コメント」「スキ」が列として並んだ表が表示されるはず。
ワンポイント
もし "サマリー_月" のシート名を変更した場合は、
sheet = spreadsheet.worksheet("シート1")
のように名前を入れ替えればOK。
4. データをDataFrameとして読み込む
ここまでで、Googleスプレッドシートとの接続とデータ取得が完了。
いよいよここから、実際のビュー推移を可視化していくで!
週×ビューの折れ線グラフ
まずは、シンプルに「週」と「ビュー」だけを使って折れ線グラフを描いてみよう。
余計な加工は一切なし。スプレッドシートの中身をそのまま使うだけや。
# @title 3-1.月×ビューの折れ線グラフ
import plotly.graph_objects as go
# ビュー列を数値に
df_view_mon["ビュー"] = pd.to_numeric(df_view_mon["ビュー"], errors="coerce")
# 折れ線グラフ作成
fig = go.Figure()
fig.add_trace(go.Scatter(
x=df_view_mon["週"],
y=df_view_mon["ビュー"],
mode="lines+markers",
name="ビュー",
line=dict(width=3)
))
fig.update_layout(
title="週ごとのビュー推移",
xaxis_title="月",
yaxis_title="ビュー数",
hovermode="x unified",
template="plotly_white",
xaxis=dict(autorange="reversed") # 👈 ここがポイント! 最新日を右に設定。
)
fig.update_traces(hovertemplate="%{y:,}")
fig.show()解説
x=df_view_mon["週"]
X軸にはスプレッドシートの「週」カラムをそのまま使う。
例:2025年10月4日-2025年11月3日y=df_view_mon["ビュー"]
Y軸は「ビュー数」。pd.to_numeric で数値化しておくのがポイント。autorange="reversed"
通常は最新日が左に来るけど、この設定で**最新が右側(=時系列順)**に並ぶ。
出力イメージ
📊 グラフには、週ごとのビュー数が線でつながって表示され、
どの週にアクセスが伸びたか一目で分かる。

まとめ
ここまでで、「週ごとのビュー推移」をPythonで自動可視化できた。
Excelやスプレッドシートでグラフを作るよりも、
Colabならコード一発で再現&更新ができる。
次は、このデータをもとに「コメント数」「スキ数」も一緒に重ねた複合グラフ を作って、
記事の反応全体を見える化していくで🔥
5. コメントとスキもまとめて可視化してみる
ここまでで、「週ごとのビュー推移」を折れ線で出せた。
でもな、“見られた”だけじゃなく、“反応された”データも見たいやん?
──そう、コメントとスキも同時に見えるようにしたい。
ただし、これらは数がビューよりずっと少ない。
だから、グラフのスケールを分けるために
ビューは折れ線(左軸)/コメントとスキは棒グラフ(右軸) にしてみた。
# @title 3-4.月×ビュー+スキ+コメント(二軸・棒グラフ)
import plotly.graph_objects as go
# 数値変換
for col in ["ビュー", "コメント", "スキ"]:
df_view_mon[col] = pd.to_numeric(df_view_mon[col], errors="coerce")
# 図の作成
fig = go.Figure()
# --- 左軸:ビュー(折れ線) ---
fig.add_trace(go.Scatter(
x=df_view_mon["週"],
y=df_view_mon["ビュー"],
mode="lines+markers",
name="ビュー(左軸)",
line=dict(width=3, color="royalblue"),
yaxis="y1"
))
# --- 右軸:スキ(棒グラフ) ---
fig.add_trace(go.Bar(
x=df_view_mon["週"],
y=df_view_mon["スキ"],
name="スキ(右軸・棒)",
marker_color="mediumseagreen",
opacity=0.6,
yaxis="y2"
))
# --- 右軸:コメント(棒グラフ) ---
fig.add_trace(go.Bar(
x=df_view_mon["週"],
y=df_view_mon["コメント"],
name="コメント(右軸・棒)",
marker_color="orange",
opacity=0.6,
yaxis="y2"
))
# --- レイアウト設定 ---
fig.update_layout(
title="月ごとのパフォーマンス推移(ビュー×スキ×コメント)",
xaxis_title="月",
yaxis=dict(
title="ビュー数",
titlefont=dict(color="royalblue"),
tickfont=dict(color="royalblue")
),
yaxis2=dict(
title="スキ/コメント数",
titlefont=dict(color="darkgreen"),
tickfont=dict(color="darkgreen"),
overlaying="y",
side="right"
),
barmode="group", # スキとコメントを横並びに
hovermode="x unified",
template="plotly_white",
xaxis=dict(autorange="reversed") # 最新週を右に
)
fig.update_traces(hovertemplate="%{y:,}")
fig.show()解説
ビュー(青):左軸の折れ線で「アクセスの流れ」を表す。
スキ(緑)/コメント(オレンジ):右軸の棒グラフで「反応の深さ」を表す。
barmode="group" でスキとコメントを横並び表示。
autorange="reversed" によって最新週が右端にくるように設定。
この構成にすると、
アクセス数の波と反応数の動きが一目で比較できる。
「読まれた週」と「反応が返ってきた週」のズレを見るのにも便利。
出力イメージ
ビューの折れ線が上を走り、
スキとコメントの棒がその下で反応の強さを支えている──
そんな“記事との対話のグラフ”が完成する。

つまり、ただのアクセス解析が「感情のログ」になるってわけや。
まとめ
ここまでで、
ビューの推移(折れ線)
スキとコメントの推移(棒グラフ)
を一枚で見える化できた。
次はこれをベースに、
「反応率(スキ÷ビュー)」や「コメント率」 みたいな
“エンゲージメント指標”も可視化や。
5. 反応率を見れば“響いた月”がわかる
ここまでで「ビュー数の推移」は見えてきたけど、
ほんまに知りたいのは──“どの月がいちばん響いたか” やと思うんよな。
だから次は、
スキ率(スキ ÷ ビュー)とコメント率(コメント ÷ ビュー) を計算して、
「見られただけ」じゃなく「反応されたかどうか」を見ていく。
月ごとの反応率(スキ率・コメント率)
まずは率(割合)だけを可視化。
「この月はスキ率が高かったな」とか、「コメントが多かったな」といった、
“質的な反応の波” が見えてくる。
ビューの多い月が必ずしも反応率が高いとは限らない。
逆に、ビューが少なくてもスキ率が高い月は、
“コアな読者が強く共感した時期” とも言える。
# @title 4-1. 月ごとの反応率(スキ率・コメント率)
import numpy as np
import pandas as pd
import plotly.graph_objects as go
# 元データをコピー
df = df_view_mon.copy()
# 数値化
for col in ["ビュー", "コメント", "スキ"]:
df[col] = pd.to_numeric(df[col], errors="coerce")
# 反応率(ビューが0や欠損の行はNaN)
df["スキ率"] = np.where(df["ビュー"] > 0, df["スキ"] / df["ビュー"], np.nan)
df["コメント率"] = np.where(df["ビュー"] > 0, df["コメント"] / df["ビュー"], np.nan)
# 折れ線グラフ(%表示)
fig = go.Figure()
fig.add_trace(go.Scatter(
x=df["週"], y=df["スキ率"] * 100,
mode="lines+markers", name="スキ率(%)"
))
fig.add_trace(go.Scatter(
x=df["週"], y=df["コメント率"] * 100,
mode="lines+markers", name="コメント率(%)"
))
fig.update_layout(
title="月ごとの反応率(スキ率・コメント率)",
xaxis_title="月",
yaxis_title="率(%)",
hovermode="x unified",
template="plotly_white",
xaxis=dict(autorange="reversed") # 最新を右に
)
fig.update_traces(hovertemplate="%{y:.2f}%")
fig.show()出力イメージ

ビュー × スキ率・コメント率
率だけだと、実際のインパクトがわかりにくいやん?
そこで、ビュー数とスキ率・コメント率を同じグラフに重ねた。
左軸:ビュー数(青い折れ線)
右軸:スキ率・コメント率(棒グラフ)
こうすると、「数字の量」と「反応の質」を同時に読める
# @title 4-2. ビュー × スキ率・コメント率(二軸:棒+折れ線)
import numpy as np
import plotly.graph_objects as go
# 数値変換
for col in ["ビュー", "コメント", "スキ"]:
df_view_mon[col] = pd.to_numeric(df_view_mon[col], errors="coerce")
# 反応率計算(ビューが0のときはNaN)
df_view_mon["スキ率"] = np.where(df_view_mon["ビュー"] > 0, df_view_mon["スキ"] / df_view_mon["ビュー"], np.nan)
df_view_mon["コメント率"] = np.where(df_view_mon["ビュー"] > 0, df_view_mon["コメント"] / df_view_mon["ビュー"], np.nan)
# --- グラフ作成 ---
fig = go.Figure()
# 左軸:ビュー(折れ線)
fig.add_trace(go.Scatter(
x=df_view_mon["週"],
y=df_view_mon["ビュー"],
mode="lines+markers",
name="ビュー(左軸)",
line=dict(width=3, color="royalblue"),
yaxis="y1"
))
# 右軸:スキ率(棒)
fig.add_trace(go.Bar(
x=df_view_mon["週"],
y=df_view_mon["スキ率"] * 100,
name="スキ率(%)(右軸)",
marker_color="mediumseagreen",
opacity=0.7,
yaxis="y2"
))
# 右軸:コメント率(棒)
fig.add_trace(go.Bar(
x=df_view_mon["週"],
y=df_view_mon["コメント率"] * 100,
name="コメント率(%)(右軸)",
marker_color="orange",
opacity=0.7,
yaxis="y2"
))
# --- レイアウト設定 ---
fig.update_layout(
title="月ごとのビュー × 反応率(スキ率・コメント率)",
xaxis_title="週",
yaxis=dict(
title="ビュー数",
titlefont=dict(color="royalblue"),
tickfont=dict(color="royalblue"),
),
yaxis2=dict(
title="反応率(%)",
titlefont=dict(color="darkgreen"),
tickfont=dict(color="darkgreen"),
overlaying="y",
side="right"
),
barmode="group",
hovermode="x unified",
template="plotly_white",
xaxis=dict(autorange="reversed") # 最新週を右へ
)
fig.update_traces(hovertemplate="%{y:.2f}")
fig.show()出力イメージ

グラフから見えてくること
たとえば、こんな見方ができる👇

つまり、「伸びた」だけじゃなく、
“どんな伸び方をしたか” が見えてくるわけや。
6. ワイの状況なら、こう読む。

上のグラフを見てほしい。
青い線が「ビュー数(見られた回数)」、緑とオレンジの棒が「スキ率」と「コメント率」。
ぱっと見てわかるとおり、2025年10月にかけてグンッと伸びてる。
単純なビュー数(青線)だけ見ると「バズった」ように見えるけど、
スキ率(緑棒)は──あんま上がってない。
つまりワイの場合、
「一気に人が来たけど、そこまで深くは読まれてない」
ってことになる。
逆に、2025年3〜5月あたりを見てみると、
ビューはそこまででも、スキ率がしっかり上がってるんよ。
この時期は、内容も方向性も試行錯誤してた頃で、
「固定の読者層」にだけちゃんと刺さってた感じやな。
こうして見ると、
バズ(月)=認知の広がり
スキ率(月)=共感の深さ
って感じで、数字の“高さ”より“意味の違い” が見えてくる。
ビューが増えた=知られた。
スキ率が上がった=響いた。
コメント率が増えた=対話が生まれた。
ワイの状況で言うなら、
“知られる”段階はクリアした。
次は“響かせる”段階に入るタイミングやな。
ちなみに、こうして「月別×反応率」を見ておくと、
「伸びた記事」と「刺さった記事」を分けて考えられる。
数字を追うだけじゃなく、
“心が動いたデータ”を拾えるのが、ログ分析の醍醐味やで。
※実際は、週データで見た方が精度高いで。
月ごとやと波がならされてまうから、
バズった記事の“瞬間風速”とか、
地味に伸びた“じわ伸び週”がわかりにくくなるんよな。笑
でもまあ、最初は「月」でもええ。
習慣化できるかどうかの方が大事やから。
慣れてきたら週集計に切り替えてみてや。
7.あとがき
長くなってもうたけど、
ここまでくると「数字の向こうにある自分の記事のクセ」が見えてくるんよな。
たとえば──
記事を分類(タグ付け) したり、文字数や構成を合わせて見たりすると、
「どんなタイプの記事が“刺さってる”のか」もだんだん見えてくる。
ワイは正直、これまでそこまで設計して出してへんかったから、
グラフ見ながら「うわ、完全にノリで投稿してたやん…」って反省したわ。笑
とはいえ、データを取るのは難しいことやない。
スプレッドシートで記録して、Colabでちょっと可視化するだけ。
(しかも無料でできる)
「お賽銭」感覚でええから、
有料部分にコード全文を置いとくから、
自分でも“記事の自己分析”やってみてや!
あと、もし「こんな分析もやってみたい」とか、
「データ渡すから一緒に見てくれ!」ってのがあったら、
コメントで教えてな。
ワイ、そういうの大好きやからw
(P.S.)
数字をいじってるうちに、
だんだん「読まれる」より「響く」を追いたくなってくる。
──それがデータ分析の副作用やで。
もし「おもろかった」「ちょっと役に立った」と思ったら、
スキ&フォローで応援してもらえるとめちゃ嬉しいです!
そして、
チップで応援してもらえたら──
「おっ、ワイのデータ記事、ちゃんと刺さっとる!」ってガッツポーズします。
8.ここから先は有料部分(コード全文)
正直、コード自体はAIに聞けば作れる。
でも、実際に動く形で整えてあるものって、意外と少ないんよな。
今回のスクリプトは、
スプレッドシート読み込み
データの整形
ビュー数+スキ率+コメント率の可視化
まで一撃で動くColab仕様になってる。
「とりあえず自分のデータで分析してみたい」
「コードをコピペで動かして、構造を真似したい」
そんな人のために、有料部分に全文コード+最小実行手順を置いとくわ。
自分の記事データで“刺さり方分析”してみてな!
ここから先は
¥ 100
よろしければ応援お願いします! いただいたチップはクリエイターとしての活動費に使わせていただきます!
