6
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?

More than 3 years have passed since last update.

そろそろバレンタインなのでラインのトーク履歴を可視化してみますかw

Last updated at Posted at 2020-02-12

バレンタインだからってわけじゃなくてじゃないんですけど,最近Githubにあるあのコントリビューションのチャートが気になっていました.

自分のコントレビューション
image.png

@torvaldsのコントリビューション
image.png

いい感じの時系列データがあれば似たようなチャートを試しに作ってみたいと前から思っていたところ,ちょうどラインのデータが簡単にダウンロードできるってことを知ったので,そのデータを使って作ってみました.

image.png

Lineのトーク履歴を取得

ラインからトーク履歴のチャットデータを保存できるって知っていました??
実は意外と簡単にできるもんなんです.

手順はこちらのサイトを参考にしています.画像のソースもそちらです.

  1. LINEアプリから保存したいトークをタップします。

  2. 右上の「V」をタップ>「設定」をタップします。

  3. 「トーク履歴を送信」から送信オプションを選択します。ここに、トーク履歴をKeepに保存します。
    image.png

  4. Keepからトーク履歴にアクセスできます。

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)))

image.png

色が薄いなと思ったら,以下のように重みをつけたりして強調させたりすることもできます.

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)))
    

chrome-capture (3).gif

以上です!メカブとか使ってさらに深く掘り下げていくのも面白そうですね.でも,もう疲れたので今日は以上ですー

6
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
6
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?