Google Chart Tools / Image Chartsで時系列折れ線グラフを作ってみる

2011年6月6日月曜日

さきのエントリに続いて脱デ部で使ってるもののお話。

やっぱり、計測する度にどの程度目標達成したかを視覚的に掴みたいところ。というわけで、

Google Chart Tools / Image Charts (aka Chart API)を使って適当な折れ線グラフを出力してみる。基本的にカンマ区切りでデータを渡してやればあとは適当にやってくれるのでとても楽。Chart Wizardでインタラクティブに項目の調整なども出来るし。

ということで
こんな感じのグラフがさっくり作れた。けど、このまま使うと「データがある分だけ等間隔に表示」ということになり、時間軸を正しく反映はしない。とはいえ今回のサービスって「毎日あるタイミングで体重を測定する」ってのを想定してるので、実用上そんなに問題は無いはず。と思ってたところ突っ込みを食らったので少々真面目に考えることに。

やること
・指定した時間レンジ内での変化を平滑化する
・指定した時間レンジよりもデータ量が少なければ空データを補完する

ここで、「過去1週間分を表示するけど未参加時期の分は表示しない」という仕様にする場合は一旦出力用のリストの各要素を'0'で初期化しておけば後が楽そう。
時間レンジの切り方には色々あると思うけれど今回は「最新の計測日時から24時間ずつ逆にたどっていき、その中で得られたデータについては平均値を取る」ということにした。極端に平滑化されたグラフが欲しいわけじゃないので移動平均とかは取らない。
Pythonのコードだとこんな感じ。
def getDailyHistoricalData(self, periodsToBack):
        info = self._fetchWeightLog()
        normalizeFor = 86400
        info.sort(key=lambda x:x['ts'], reverse=True)
        lastBoundary = info[0]['ts'] - normalizeFor
        avgList = list()
        cnt = 0
        sum = 0
        for v in info:
            if lastBoundary < float(v['ts']):
                sum += float(v['wt'])
                cnt += 1
            else:
                avgList.append(('%.2f' % (sum / cnt)) if cnt != 0 else '0')
                lastBoundary -= normalizeFor
                cnt = 0
                sum = 0
                if pos == periodsToBack:
                    break
        # catch last one
        if cnt != 0:
            avgList.append(('%.2f' % (sum / cnt)) if cnt != 0 else '0')
        if len(avgList) < periodsToBack:
            avgList.extend(['0' for i in range(periodsToBack - len(avgList))])
        avgList.reverse()
        return avgList
最新データから逆に古いデータへ辿っていく形で、データが足りなければ最後のほうで追加してる。リスト長が固定なのでインデックス指定でいじってもいいのだけど、appendでペチペチやっていくのが楽だったので最後にreverseかけてる。 これで無事
一日でデータ投入しまくっても平均値のみ1日1回分反映されるようになった。けれど多分これは不具合ある。1日・2日と計測をサボった際、この実装だとその区間データは0になるはずなんだけど、どっちかというと補完処理してほしいだろうなぁ。

で、Google Image Chartsは http://chart.apis.google.com/chart?chs=220x110&cht=lc&chco=3072F3&chm=B,DDDDFF,0,0,0&chd=t:1,2,3,4 というようなURLでimgタグを貼るとグラフ描画してくれるよという程度。あとはChart Wizardのギャラリーとか見ながら頑張るのがいい。使える記法のリファレンスは結構長い。

0 件のコメント:

コメントを投稿