ニコ動の人気タグ遷移を一発でアニメーション化できるpythonライブラリが生まれたらしいので試してみた

# AnimatedWordCloudというライブラリを作りました。
### どんなライブラリ?
- WordCloudを時系列順に処理してくれるライブラリです。
↓イーロンマスクの呟き2012から2017までの描画
![68747470733a2f2f6769746875622e636f6d2f6b6f6e6272617068617435312f416e696d61746564576f7264436c6f75642f6173736574732f3130313832373439322f38393035326332302d623232382d343264382d393231652d656261653966376533306130.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3311006/f2390428-2d79-dbed-d253-306dfa666caf.gif)

# ダウンロード方法
### PyPIで配布中です
https://pypi.org/project/AnimatedWordCloudTimelapse/

使う時は
```python
pip install AnimatedWordCloudTimelapse
```
としてダウンロードしてください。
# 元リポジトリ
https://github.com/konbraphat51/AnimatedWordCloud

ここにあります。StarやContributeをしてくださるとありがたいです。
# 使い方

まずは可視化するためのデータが必要です。そこで, 今回はニコニコ動画のデータセットを使いましょう。ニコニコ動画の2007年から2021年のタグを可視化することを目指します。[ニコニコ動画データセット](https://www.nii.ac.jp/dsc/idr/nico/nicopedia-apply.html)
このデータは重いので今回はそのうちの一つである0000.jsonlを可視化します。
必要事項を記入したら0000.jsonlをwgetで取得しましょう
```bash
!wget https://dlsv.dsc.nii.ac.jp/idr/hogehoge/hugahuga/nicocomm/data/video/0000.jsonl
```
ここからはデータ整形を行っていきます。今回はみんなに優しくGoogle Colaboratoryでの実行を仮定しています。
まずはjsonlデータを[date, tag]のcsvデータに整形しましょう。
```python
import json
json_data = []
with open('0000.jsonl', 'r') as json_open:
    for line in json_open:
        json_data.append(json.loads(line))


csv_data = [["date", "tag"]]
for data in json_data:
  tags = data["tags"].split(" ")
  for tag in tags:
    csv_data.append([data["upload_time"], tag])

import csv
with open("tags.csv", "w") as f:
  csv_writer = csv.writer(f)
  csv_writer.writerows(csv_data)
```
Google Colaboratoryの/content/以下にtags.csvが保存されているので, それをpandasで読みこんで前処理をしましょう。
```python
import pandas as pd
df = pd.read_csv("/content/tags.csv")

df["date"] = pd.to_datetime(df["date"]) #datetime型にする

df.head(5)
```

| |date	|tag|
|----|----|---|
0	|2007-03-06 12:14:17+09:00	|MAD
1	|2007-03-06 12:14:17+09:00	|アニメ
2	|2007-03-06 12:14:17+09:00	|最終兵器彼女
3	|2007-03-06 19:27:26+09:00	|3月6日投稿動画
4	|2007-03-06 19:27:26+09:00	|IDニ謝レ

読み込むと上のような表が出力されます。このデータを以下の手順に沿って前処理しましょう。
1. dateをdatetime型に変換してsortする
2. 厳密な時間ではなく投稿年で再ラベリング
```python
df = df.sort_values(by='date') #dateでsort
df["year"] = df["date"].dt.year #yearに関して再度ラベリング, カラムを追加
```
これで前処理は終了です。ここで僕らのチームが作成したAnimatedWordCloudライブラリをインストールしておきましょう。
```python
pip install AnimatedWordCloudTimelapse
```
ここで, WordCloudのアニメーションを制作するためにはAnimatedWordCloudライブラリのanimateという関数を用いますが, これの入力のために, List[year, dict[word, 登場頻度]]という形のデータを作る必要があります。登場頻度も全てをカウントしていると数が多すぎるため, 上位100個にしましょう。
```python
timelapse = []

for year in df["year"].unique():
  df_year = df[df["year"] == year]
  counter = df_year["tag"].value_counts()[:100]

  word_vector = counter.to_dict() #{word: 登場頻度}の辞書に

  timelapse.append((str(year), word_vector))
```
このデータが作れたらついにWordCloudのアニメーションを制作することができます。制作する前に, [NotoSansJP-VariableFont_wght.ttf](https://fonts.google.com/noto/specimen/Noto+Sans+JP)をダウンロードしておいて/contentの下に置き, 日本語の文字列に対応しておきましょう。
以下のコードではConfigというものを指定しています。簡単に今回使ったConfigを紹介しておきます。
- font_path: 表示に使うフォントのパスです。
- output_path: gif画像出力先のパスです。**現Versionでは必ず指定してください。**
- image_width, image_height: 出力gif画像のサイズです。
- verbosity: gif画像の作成状況の表示を行うか否かを指定します。silent, minor, debugの3つのモードがあり, silentは作成状況を表示しません, minorは進捗バーが表示されます。debugは全ての進捗が表示されます。minorとdebugモードではgif画像出力先のパスも表示されます。
- n_frames_for_interpolation: ある時間とある時間の間を埋めるのにどれぐらいのフレームを使うのかを指定します。デフォルトでは20ですが今回はqiitaにあげれる画像容量の関係で10にしています。補間フレームは文字の線形移動によって実装されています。今後線形以外の補間方法が追加される予定です。
```python
from AnimatedWordCloud import animate, Config

config = Config(
    font_path="/content/NotoSansJP-VariableFont_wght.ttf",
    output_path="/content/",
    image_width=1600,
    image_height=1200,
    verbosity="debug",
    n_frames_for_interpolation=10
)

result = animate(timelapse, config)
#resultには出力gifが保存されている場所のpathが与えられる。
```
上のコードを実行すると以下の表示がでます。この表示が出れば保存成功です。
```
------------------------------Success!------------------------------
    your animation was successfully saved in /content/output.gif    
--------------------------------------------------------------------
```
作成されたgif画像はこんな感じです。
![output-2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3311006/25d837dd-f402-a960-10eb-855f87f95822.gif)

作成後, フレームごとの画像も保存されてしまうため, 気になる方はMac, Linux, WSLの方はrmコマンドで削除すると良いでしょう。
```bash
#例
rm /content/*.png
```

# 今後の展望
今はgif画像の出力のみですが, 正直言って娯楽以外ではデータの可視化としては使いづらいと思います。そこで, 今後のMajor updateとしてjsonによる出力を追加し, フロントエンドでの実装に役立つような機能を追加予定です。お楽しみにしていてください。

# 他の実装例
相方が何通りか作成してくれています。是非遊んでみてください。

https://github.com/konbraphat51/AnimatedWordCloudExampleJP/tree/main

https://github.com/konbraphat51/AnimatedWordCloudExampleElon