termgraph を自分のスクリプトから使いたい
ターミナルに簡単にグラフを書きたいと思って PyPI を探してみたら termgraph というのを見つけたものの、README.md を見ると何やらコマンドとして使うのが想定されているようで Python スクリプトから呼び出す方法については書かれていなかった。 仕方ないので termgraph の中を見てみて、こんな感じでやれば自分の Python スクリプトから termgraph 内の関数を呼び出してグラフを書けるよ、という内容のメモ。
termgraph に付属のサンプルデータにある data/ex4.txt を例にする。
# Example Data Set 4 with 2 Categories
@ Boys,Girls
2007,183.32,190.52
2008,231.23,5.0
2009,16.43,53.1
2010,50.21,7
2011,508.97,10.45
2012,212.05,20.2
2014,30.0,20.0
- 2007 年から 2014 年までの、Boys と Girls についてのなんらかの値が入っている。
- # で始まる行はコメント
- @ で始まる行は、データ行の列名だと思っておけば良い。termgraph の中では categories と呼ばれている
- 以降の行は、label,boys,girls という並びでカンマ区切りでデータが置かれている
お手本
termgraph コマンドを使うと、こんなグラフが書ける。
% termgraph ~/src-misc/termgraph/data/ex4.dat
▇ Boys ▇ Girls
2007: ▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 183.32
▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 190.52
2008: ▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 231.23
▏ 5.00
2009: ▇ 16.43
▇▇▇▇▇ 53.10
2010: ▇▇▇▇ 50.21
▏ 7.00
2011: ▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 508.97
▇ 10.45
2012: ▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 212.05
▇ 20.20
2014: ▇▇ 30.00
▇ 20.00
%
コマンドを使うのではなく、自分の Python スクリプトから termgraph の中のものを使って同じことをやろう、というのが目標。
概要
データを用意して、以下の termgraph 内の関数を呼び出す。
- termgraph.check_data
- termgraph.print_categories
- termgraph.chart
termgraph.chart 関数
最終的に termgraph.chart 関数を呼んでグラフを書くことになる。
def chart(colors: List, data: List, args: Dict, labels: List) -> None:
"""Handle the normalization of data and the printing of the graph."""
colors, data, args, labels を用意する必要がある。
- colors - チャートの色の list
- data - チャートのデータの list
- args - termgraph.chart 関数のオプションを指定する dict
- labels - 各要素の名前
colors リスト
上の例では Boys / Girls ともに端末の文字の色でグラフが描かれるが、termgraph コマンドに --color {blue,red} とオプションを付け加えると、Boys は青で Girls は赤でグラフが描かれる。
この colors リストは自分で用意する必要はない。termgraph.check_data 関数の返り値を colors にする。
colors = tg.check_data(labels, data, args)
では、どのように色を指定するのかというと、args['color'] に値を入れておく。端末の文字色でよければ None を入れる。categories の要素ごとに色を変えたい場合リストに色を指定する、例えば Boys は青で Girls は赤にしたいという場合には、args['color'] = ['blue', 'red'] という感じ。このリストの要素数は、categories リストの要素数と等しくなくてはならない。
指定できる色は、termgraph.AVAILABLE_COLORS に定義されている。
# ANSI escape SGR Parameters color codes
AVAILABLE_COLORS = {
"red": 91,
"blue": 94,
"green": 92,
"magenta": 95,
"yellow": 93,
"black": 90,
"cyan": 96,
}
色を追加で定義したいのなら、この AVAILABLE_CHARTS に追加すれば良い。例えば白なら tg.AVAILABLE_COLORS = {'white': 97} と書く。 wikipedia の ANSI escape code のページを見ると、30 から 37 の値も使えそうではあるが試してはいない。
labels リスト
2007 から 2014 までの文字列のリストを作っておけば良い。
labels = ['2007', '2008', '2009', '2010', '2011', '2022', '2014']
data リスト
[boysの値,girlsの値] のリストを作っておけば良い。こんな感じ。
data = [
# Boys, Girls
[183.32, 190.52],
[231.23, 5.0 ],
[ 16.43, 53.1],
[ 50.21, 7 ],
[508.97, 10.45],
[212.05, 20.2 ],
[ 30.0, 20.0 ],
]
args dict
termgraph コマンドのヘルプ (termgraph --help) を参考に dict を作っていけば良いのだが、termgraph.chart 関数や termgraph.check_data 関数を呼ぶだけなら不要だったりするものや、そもそも使われていないものもある。。。
termgraph.chart を呼ぶために必須なもの
オプション名 | タイプ | オプションの意味 |
---|---|---|
width | int | グラフの幅。デフォルト 50。 |
format | str | 各棒の後に数値を表示する際の形式。デフォルト {:<5.2f} |
suffix | str | 各棒の後に表示した数値の後につける文字列。 % とかをつけたいなら。 |
no_labels | bool | 各棒の先頭にラベルを表示するかどうか。 |
no_values | bool | 各棒の後に値を表示するかどうか。 |
color | list | 色名をリストで指定。 ["blue", "red"] とか。指定がなければ None を入れておけば良い。 |
vertical | bool | 横ではなく縦にグラフを書きたい! |
stacked | bool | 各カテゴリを合わせたグラフにしたい! |
histogram | bool | ヒストグラムでお願い! |
bins | int | ヒストグラムにしたときの bin の数。 デフォルト 5。 |
different_scale | bool | Categories have different scales らしいが調べてない |
termgraph コマンドのオプションとして定義されているが、chart や check_data を使うにあたっては不要なもの
- title
- calendar
- start-dt
- custom-tick
- delim
タイトルは自分で書けばいい。
calendar と start-dt は、カレンダーヒートマップを書きたい場合に使う。termgraph.chart 関数ではなく、termgraph.calendar_heatmap 関数を呼ぶ。
custom-tick は、グラフを描くときの文字を変更したい場合に使う。
delim は、データ入力をファイルから行うときに区切りもじを指定するために使う。(termgraph.DELIM の値を変える。)
termgraph コマンドのオプションとして定義されているが使われていないもの...
- space-between
- label-before
というわけで、こんな感じで args を用意すればよい。
args = {
'width': 50,
'format': '{:<5.2f}',
'suffix': '',
'no_labels': False,
'no_values': False,
'color': None,
'vertical': False,
'stacked': False,
'histogram': False,
'bins': 5,
'different_scale': False
}
categories リスト
凡例を表示するには、termgraph.print_categories(categories, colors) を呼ぶ。 categories リストは ['Boys', 'Girls'] として用意する。
組み合わせてみる
全部合わせてみると、こんな感じのスクリプトになる。
from termgraph import termgraph as tg
# data/ex4.dat
categories = ['Boys', 'Girls']
labels = ['2007', '2008', '2009', '2010', '2011', '2022', '2014']
data = [
# Boys, Girls
[183.32, 190.52],
[231.23, 5.0 ],
[ 16.43, 53.1],
[ 50.21, 7 ],
[508.97, 10.45],
[212.05, 20.2 ],
[ 30.0, 20.0 ],
]
args = {
'width': 50,
'format': '{:<5.2f}',
'suffix': '',
'no_labels': False,
'no_values': False,
'color': None,
'vertical': False,
'stacked': False,
'histogram': False,
'bins': 5,
'different_scale': False
}
colors = tg.check_data(labels, data, args)
if categories:
tg.print_categories(categories, colors)
tg.chart(colors, data, args, labels)
hoge.py として保存して、実行してみる。
% python hoge.py
▇ Boys ▇ Girls
2007: ▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 183.32
▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 190.52
2008: ▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 231.23
▏ 5.00
2009: ▇ 16.43
▇▇▇▇▇ 53.10
2010: ▇▇▇▇ 50.21
▏ 7.00
2011: ▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 508.97
▇ 10.45
2022: ▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 212.05
▇ 20.20
2014: ▇▇ 30.00
▇ 20.00
%
できあがり。