バレンタインだからってわけじゃなくてじゃないんですけど,最近Githubにあるあのコントリビューションのチャートが気になっていました.
@torvaldsのコントリビューション
いい感じの時系列データがあれば似たようなチャートを試しに作ってみたいと前から思っていたところ,ちょうどラインのデータが簡単にダウンロードできるってことを知ったので,そのデータを使って作ってみました.
Lineのトーク履歴を取得
ラインからトーク履歴のチャットデータを保存できるって知っていました??
実は意外と簡単にできるもんなんです.
手順はこちらのサイトを参考にしています.画像のソースもそちらです.
-
LINEアプリから保存したいトークをタップします。
CalmapとPandasでデータをすぐに可視化!
まず,以下のパッケージをインポートしていることにします.
import datetime, calmap
import japanize_matplotlib
import pandas as pd
from matplotlib import pyplot as plt
from collections import defaultdict
import warnings
warnings.simplefilter("ignore")
そして次にデータの集め方について考えます.データ取得の工程に出てきたこちらの画像の右側にテキストデータがありますが,このようなフォーマットでデータを読み込むと仮定します.(※僕の携帯は英語設定なので,少しだけフォーマットが違いますが,ほとんど同じです!)
日付だけの行があって,その下に時間,人,チャット内容が一つの行になっていますね(電話・スタンプ・ファイルなども面倒なのでチャットして考える!).ここに着目して,日付の行だったらTrueを返す,isNewDay()
とチャットの行だったらTrueを返すisChat()
関数を作ります.
日付 | ||
---|---|---|
時間 | 人 | 内容 |
時間 | 人 | 内容 |
時間 | 人 | 内容 |
日付 | ||
---|---|---|
時間 | 人 | 内容 |
時間 | 人 | 内容 |
def isNewDay(line):
line = line.strip().replace(' ','')
elements = line.split(',')
if len(elements) == 2:
day, date = elements
try:
assert day in ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
assert datetime.datetime.strptime(date, '%m/%d/%Y')
return True
except (AssertionError, ValueError) as e:
pass
return False
def isChat(line):
elements = line.split('\t')
if len(elements) == 3:
time, person, activity = elements
try:
assert datetime.datetime.strptime(time, '%H:%M')
assert person in [PERSON1, PERSON2]
return True
except (AssertionError, ValueError) as e:
pass
return False
もし読み込むデータのテキストファイルのフォーマットが若干違ったりすれば,これらの関数の内容を修正する必要があります.
ここまできたら,あとはループで日付毎にチャットの回数を数えれば良いです.僕はしたのようにdefaultdictを使って以下のように数えました.日付順にチャットが並んでいると仮定しているので結構ガバガバな感じで書いています(笑.
d = defaultdict(lambda: 0)
with open(PATH_TO_DATA) as f:
for line in f.readlines():
# New day
if isNewDay(line):
day, date = line.split(',') #
month, day, year = list(map(int, date.split('/')))
# Chat Event
if isChat(line):
index = datetime.datetime(year, month, day)
d[index] += 1
チャットの回数を数え上げたら,今度は可視化します.これにはcalmapパッケージを使います.
使い方はすごく簡単で,基本的には時系列上に並んでいるpandasのSeriesをぶちこめばOKです.
s = pd.Series(d)
calmap.calendarplot(s, monthticks=3, cmap='PuRd', daylabels='月火水木金土日',
fig_kws=dict(figsize=(8, 4)))
色が薄いなと思ったら,以下のように重みをつけたりして強調させたりすることもできます.
import ipywidgets as widgets
from ipywidgets import interact, interact_manual
@interact
def emph(x=(-0.5, 0.5, 0.1)):
s = pd.Series(d)
s *= s**x
calmap.calendarplot(s, monthticks=3, cmap='PuRd', daylabels='月火水木金土日',
fig_kws=dict(figsize=(8, 4)))
以上です!メカブとか使ってさらに深く掘り下げていくのも面白そうですね.でも,もう疲れたので今日は以上ですー