Plotly の練習がてら、ディスク使用量を Sunburst Chart で可視化してみました。
Plotlyとは
Plotly はチャートの生成等を行うためのグラフィックライブラリです。
今回使用するのは Python のライブラリ (plotly.py) ですが、チャート自体は HTML + JavaScript で出力されます。 直に JavaScript のライブラリ (plotly.js) を使ってチャートを書くこともできます。
ディスク使用量の計算
フォルダのサイズを次のように計算する
- フォルダ内のファイル・フォルダを列挙し、次のように処理する
- ファイルならそのサイズを加算
- フォルダならそれに対し、この処理を再帰呼び出ししてサイズを計算し、サイズを加算
この処理を Python のコードに落とし込むと次のようになります。
import os def f(current): total = 0 if os.path.islink(current): return 0 elif os.path.isfile(current): total = os.path.getsize(current) else: try: children = os.scandir(current) except: return 0 for child in children: total += f(child.path) return total f('c:\\')
ディスクのサイズが大きいと、この計算は数分かかる場合があります。
フォルダのサイズを速く計算するのはなかなか難しいようです。
Sunburst Chart の作成
まずは適当な例を考えチャートを描画してみましょう。
hoge/ ├ fuga/ │ ├ fuga1.txt (5 MiB) │ └ fuga2.txt (10 MiB) └ piyo.txt (20 MiB)
このようなフォルダ構成の場合、ファイル・フォルダのサイズを表にすると次のようになります。
パス | サイズ(MiB) |
---|---|
hoge/ | 35 |
hoge/fuga/ | 15 |
hoge/fuga/fuga1.txt | 5 |
hoge/fuga/fuga2.txt | 10 |
hoge/piyo.txt | 20 |
この情報を Plotly の入力に変換していきます。
labels = [] parents = [] values = [] def add_data(path, parent, size): labels.append(path) parents.append(parent) values.append(size) add_data('hoge/', '', 35) add_data('hoge/fuga/', 'hoge/', 15) add_data('hoge/fuga/fuga1.txt', 'hoge/fuga/', 5) add_data('hoge/fuga/fuga2.txt', 'hoge/fuga/', 10) add_data('hoge/piyo.txt', 'hoge/', 20)
Sunburst Chart の入力は labels
, parents
, values
の3つです。
labels
にはそのデータのラベルを指定します。チャートを表示したときにデータの部分にラベルが表示されます。parents
にはそのデータの親のラベルを指定します。どのラベルのデータがどのラベルの下に表示されるかをここで決めます。values
にはそのデータの値(今回はサイズ)を指定します。
このようにして作った入力を Plotly に突っ込みます。
https://plotly.com/python/sunburst-charts/
from plotly import graph_objects as go trace = go.Sunburst( name='', labels=labels, parents=parents, values=values, branchvalues='total' ) figure = go.Figure( data=trace ) figure.show()
このコードを実行すると次のようなチャートが表示されます。
ディスク使用量を Sunburst Chart 化
最初に示した関数では、親フォルダの情報が取れないのと、 labels
, parents
, values
を記録する部分がないので、次のように修正します。
labels = [] parents = [] values = [] def f(current, parent): total = 0 if os.path.islink(current): return 0 elif os.path.isfile(current): total = os.path.getsize(current) else: try: children = os.scandir(current) except: return 0 for child in children: total += f(child.path, current) labels.append(current) parents.append(parent) values.append(total / 1024 ** 3) return total
これで作ったデータを Plotly に突っ込みます。
私のCドライブで実行すると次のようになりました。
これで、どこに大きなデータが保存されているか一発で見つけられますね!
コードの全体は下に置いてあります(※ 若干この記事で説明したコードから変更した箇所があります)。