読者です 読者をやめる 読者になる 読者になる

まんぼう日記

takataka's diary

走り納め 27km & Training Center Database XML ファイルを読む python プログラム

走り納め 27km

 

今度の年末年始は仕事が片付かへんで

\(^^)\...

     .../(^^)/

な予定のたかたかです.

 

とか言いながら,天気ええし大晦日やしっちうことで,走り納めに行ってきました.

 瀬田川右岸 → 石山寺 → 大平 → 醍醐大津線 → 横峰峠で折り返して戻る

てルート.で,こういうことになりました.

Session Type: running
Start: 2015-12-31T11:10:16+09:00
Distance: 27.00 km
Time: 03:06:31
Pace: 06:54 min/km
Calories: 1715 kcal

https://www.runtastic.com/ja/users/takashi-takahashi-13/sport-sessions/1106390406

f:id:takatakamanbou:20151231235355p:plain

 

今回は1枚も写真撮ったりせんと走る&歩くだけでした.景色とか興味あるひとは

醍醐大津線 カテゴリーの記事一覧 - まんぼう日記 へどうぞ.

 

 

Training Center Database XML ファイルを読む python プログラム

Runtastic の .tcx なデータを可視化したい

実は,上のグラフはいつもと違ってます.というのも,最近 Runtastic のウェブサイトの表示が大幅に更新されまして....全体としてはずいぶんよくなったと思うんですが,これまでたかたかがまんぼう日記に貼り付けるために使ってた,時間 vs 高度/ペース/心拍数のグラフを画像として出力する機能がなくなってしまいました.しゃーないから,先日( 背景画像の変更とX登校プチ11km - まんぼう日記 )はブラウザの画面をグラブして画像を作ったりしたんですが,これがなかなか面倒くさい....そのうえ,右側に表示されるはずのペースと心拍数の目盛りが見えへんちう不具合もあります.

 

むー,どないかならへんかなー....あ,「オプション」に「.gpx/.tcx/.kmlファイルとしてエクスポート」なんてメニューがある.ひょっとすると,書きだしたファイルからデータを拾って自分でグラフ描けるんちゃうか.

 

というわけで,python 使ってやってみました.ソースはこちら: 

https://gist.github.com/takatakamanbou/c9aafe8d2d63c1a80530

 

まずは,3種類のファイルをエクスポートして中身を覗いてみたら,3つともXMLのファイルでした.いずれも数秒ごとに計測された緯度,経度,高度の値が格納されており,拡張子が .gpx のものと .tcx のものには心拍数のデータも含まれているようです.で,.tcx だけはスタートからの距離ももってました.というわけで,まずは拡張子 .tcx のファイルを対象とすることに決定.

 

XML の解析

拡張子 .tcx のファイルのフォーマットは,ガーミン が作ったようです:

Garmin Training Center Database XML - Welcome

 XML で記述されているので,XML を扱えるひとにならないといけません.python で XML データを解析するにはいろんな手段があるみたいですが,ElementTree っちゅうのを使うことにしました.

 上記を見ながらしばらく試行錯誤したら,とりあえず必要な情報を読み込めるようになりました.詳しくはソースを解読してね.

 

時刻情報の扱い

XMLのデータは読めるようになりましたが,時刻が

2015-12-31T02:10:16.000Z

のような表記( ISO 8601 って規格やそうです.cf. ISO 8601 - Wikipedia )になってます.UTC( 協定世界時 - Wikipedia )ですな.この ISO 8601 形式は,python の datetime モジュール

8.1. datetime — 基本的な日付型および時間型 — Python 2.7.x ドキュメント

では受け付けてくれへんので,どうにかしないといけません(datetime.datetime.isoformat() で出力はできるけど).適当に文字列処理して +9時間する,っちゅういい加減な手もありますが,せっかくなんでちゃんと変換する方法を調べてみました. 

 

ISO 8601の日付フォーマットをPythonでparseするには という記事によると,dateutil (  python-dateutil 2.4.2 : Python Package Index ) というモジュールを使えばよいそうな.MacPorts では

$ sudo port install py27-dateutil

でインストールできました.こんな風にISO 8601形式の文字列を datetime オブジェクトに変換することができます.

In [3]: import datetime
In [4]: import dateutil.parser
In [5]: dateutil.parser.parse('2015-12-31T02:10:16.000Z')
Out[5]: datetime.datetime(2015, 12, 31, 2, 10, 16, tzinfo=tzutc())

 

次は,TimeZoneを変更します.Pythonの日付処理とTimeZone | Nekoya Press という記事を参考に,次のようにすると JST に変換できました.

In [6]: import pytz
In [7]: hoge = dateutil.parser.parse('2015-12-31T02:10:16.000Z')
In [8]: hoge.astimezone( pytz.timezone( 'Asia/Tokyo' ) )
Out[8]: datetime.datetime(2015, 12, 31, 11, 10, 16, tzinfo=<DstTzInfo 'Asia/Tokyo' JST+9:00:00 STD>)

 

ここまでで, Runtastic の .tcx ファイルに数秒間隔で書き込まれている Trackpoint のデータを読んで,セッション開始からの経過時間ごとの距離や高度などを求めるプログラムが作れるようになりました.時間と距離から,ペースも算出できます.リンク先に置いといたプログラムでは,現在とそれから10個前の Trackpoint の間の経過時間と距離からペースを算出するようにしてみました.直前の Trackpoint との差を使うより安定した値がでるかなと思って.

 

一時停止の扱い

 

さあこれでうまくいく,ぐふふ...とプログラムを実行してグラフを描いてみると,うまく...いってません.数カ所,ペースが極端に遅くなってるところがあります.Runtastic には信号待ちとかでセッションを自動停止させる機能があるんやけど,その情報はファイルに書かれてへんからうまく扱えてないのでした.

 

ファイルの中身を眺めてみたら,自動停止してた期間のデータは書き込まれないみたいなので,前後の Trackpoint の間の経過時間が通常(3秒前後)より大きかったら一時停止してたとみなす,ということにしてみました.いい加減ですが,うまくいってるようです.

 

matplotlib で縦軸の範囲の異なるグラフをまとめて描く

 

セッション開始からの経過時間ごとの距離,高度,心拍数という,欲しかったデータが手に入るようになり,グラフも描けるようになりました.でも,これらのグラフは縦軸の範囲が異なるので,一つにまとめて描けません.どうにかしたいと調べてみたら,こんなサンプルがありました:

api example code: two_scales.py — Matplotlib 1.5.0 documentation

真似していじってみたら,ばっちり.そしたら,もっと見やすいグラフにしたいと欲が出てきて,さらに改良して完成.できたグラフとプログラムが,↑のんです.

 

夕方に作業開始してから6時間あまり,完成したら除夜の鐘鳴りはじめましたよ.大晦日の夜に何やってんねん (^^;