CORDEA blog

Android applications engineer

GlueLangを動かしてみる。

とりあえず、私のMacでGlueLangのサンプルを動かすまでの話です。
Ubuntuでは上手くいくのですが、私のMacだと始めにちょっとこけたのでメモ。

  • 2015/01/13 追記

 現在はLLVM 6.0でも動作することを確認しました。

GlueLang

 

ryuichiueda/GlueLang · GitHub


Mac OS X (10.9.5)

 

使ってみる

% git clone https://github.com/ryuichiueda/GlueLang/
% cd GlueLang
% make
% ./glue EXAMPLE/if_then_else.glue

私の場合EXAMPLEのfizzbuzz.glueとif_then_else.glueがCommand errorで動作しなかった。

 

こけた原因と対処法

原因

おそらくgccとg++のversion

対処法
% ./glue EXAMPLE/if_then_else.glue

Execution error at line 5, char 3
        line5: ? /usr/bin/true
                 ^
        Command error

        process_level 1
        exit_status 127
        pid 34374

  ...

% brew tap homebrew/versions
% brew install gcc48
% sudo ln -sf /usr/local/bin/gcc-4.8 /usr/bin/gcc
% sudo ln -sf /usr/local/bin/g++-4.8 /usr/bin/g++

% make clean
rm -f glue Arg.o Command.o CommandLine.o Comment.o Element.o Environment.o Feeder.o IfBlock.o Import.o Pipeline.o Script.o TmpFile.o VarString.o main.o /usr/local/bin/glue

% make
g++ -Wall -O3 --static -std=c++11   -c -o Arg.o Arg.cc
g++ -Wall -O3 --static -std=c++11   -c -o Command.o Command.cc
g++ -Wall -O3 --static -std=c++11   -c -o CommandLine.o CommandLine.cc
g++ -Wall -O3 --static -std=c++11   -c -o Comment.o Comment.cc
g++ -Wall -O3 --static -std=c++11   -c -o Element.o Element.cc
g++ -Wall -O3 --static -std=c++11   -c -o Environment.o Environment.cc
g++ -Wall -O3 --static -std=c++11   -c -o Feeder.o Feeder.cc
Feeder.cc: In member function 'int Feeder::countIndent()':
Feeder.cc:476:20: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
  while(i < p->size()){
                    ^
g++ -Wall -O3 --static -std=c++11   -c -o IfBlock.o IfBlock.cc
IfBlock.cc: In member function 'virtual int IfBlock::exec()':
IfBlock.cc:136:29: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
  for(int i=0;i<m_nodes.size();i++){
                             ^
g++ -Wall -O3 --static -std=c++11   -c -o Import.o Import.cc
g++ -Wall -O3 --static -std=c++11   -c -o Pipeline.o Pipeline.cc
g++ -Wall -O3 --static -std=c++11   -c -o Script.o Script.cc
g++ -Wall -O3 --static -std=c++11   -c -o TmpFile.o TmpFile.cc
g++ -Wall -O3 --static -std=c++11   -c -o VarString.o VarString.cc
g++ -Wall -O3 --static -std=c++11   -c -o main.o main.cc
g++ -o glue Arg.o Command.o CommandLine.o Comment.o Element.o Environment.o Feeder.o IfBlock.o Import.o Pipeline.o Script.o TmpFile.o VarString.o main.o

% ./glue EXAMPLE/if_then_else.glue
OK
a
OK
OK

 

ここには書いておりませんがgcc,g++のVersionを上げた後、fizzbuzz.glueも正常に動くことを確認しています。

gcc, g++ Version

上げる前
% gcc --version
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.10.sdk/usr/include/c++/4.2.1
Apple LLVM version 6.0 (clang-600.0.56) (based on LLVM 3.5svn)
Target: x86_64-apple-darwin13.4.0
Thread model: posix
% g++ --version
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.10.sdk/usr/include/c++/4.2.1
Apple LLVM version 6.0 (clang-600.0.56) (based on LLVM 3.5svn)
Target: x86_64-apple-darwin13.4.0
Thread model: posix

 

上げた後
% gcc --version
gcc (Homebrew gcc48 4.8.3) 4.8.3
Copyright (C) 2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
% g++ --version
g++ (Homebrew gcc48 4.8.3) 4.8.3
Copyright (C) 2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

 
 

Ubuntu

普通に動作しているのでversionだけ。

Version

% uname -r
3.16.7-tinycore64
% cat /etc/issue
Ubuntu 14.04.1 LTS \n \l
% gcc --version
gcc (Ubuntu 4.8.2-19ubuntu1) 4.8.2
Copyright (C) 2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
% g++ --version
g++ (Ubuntu 4.8.2-19ubuntu1) 4.8.2
Copyright (C) 2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

niconicoのコンテンツ検索apiを用いたアニメ間距離の可視化 続き

前回は距離の算出やノイズに悩まされ、あまり良い結果が得られなかったのであの後もしばらく続けておりました。
これ以上放っておくと手順を忘れそうなので、ここらでまとめておきます。

とはいえ一ヶ月前くらいにやったことなので既に結構忘れていて余り書くことがない...すみません。

 
とりあえずプリキュアとかの続編がある程度固まってくれているのがちょっと嬉しいです。

 

前回からの変更点

  • 2010-2014作品から、2000-2014年に取得範囲を変更
  • 説明文にアニメタイトルを含むものまで取得していましたが、関係ないものが多くヒットするようなので動画タイトルかタグのいずれかにアニメタイトルを含むものだけを取得するように変更(getdataFromWikipedia.py)
  • 動画件数が200件に満たないものは除外(getSearchResult.py)
  • 取得した動画のタグに「アニメ」タグを含まないものは除外(tagParseJSONforCount.py)
  • タグの出現回数ではなく、アニメ1作品の総タグ数に占める対象タグの割合に変更(tagParseJSONforCount.py)
  • tf-idfを算出し、一定値に満たないタグは除外することで、特異的なタグが距離に反映されやすくなるように機能追加(calcTfidf.py)
  • あまり関係はないですが、出力の関係でTree ViewerをDendroscopeからEPoSに変更
  • 他にもMeCabを使って形態素解析してMDSしてみたり(tagMeCabParseJSONforCount.py)


 

結果

Dendrogram
画像サイズが大きいのでご注意下さい。

距離の算出はピアソンです。


GitHubnewickデータもおいておきます。


 

手順

python getSearchResult.py animes_2000-2014.txt
python tagParseJSONforCount.py animes > tags_anime_dataset.tsv
python calcTfidf.py tags_anime_dataset.tsv > tfidf_anime_dataset.tsv
awk -F "\t" '{if($2>=1.0){print $0}}' tfidf_anime_dataset.tsv > tfidf_1.0_anime_dataset.tsv
gawk -f cut_file.awk tfidf_1.0_anime_dataset.tsv tags_anime_dataset.tsv > tags_1.0_anime_dataset.tsv
R CMD BATCH hclust.R


 

コード類

GitHub


 

【Python】niconicoのコンテンツ検索apiを用いたアニメ間距離の可視化【R】

はじめに

3連休中あまりに暇だったので、動画に付いているタグによってアニメ間の距離はどう見えるかを調べた結果と作ったプログラム群。

今回対象としているアニメ

2010-2014年までのアニメ、823作品
Wikipediaから取得

主に使用しているライブラリ等

  • Python
    • scikit-learn
    • matplotlib
  • R
    • ctc
    • amap

やってみて感じたこと

問題点
  • 1700件までしか取得できないapi仕様
  • モノによってノイズが多く入り込む可能性がある
  • アニメによって数の差がかなりある
利点
  • 勢いのあるサービスであり、今後もデータが増える見込みがある
  • サムネイル画像習得による大規模画像解析が可能
  • 使い方次第でビッグデータになり得る


 
 

手順

ソースコードGitHubにあります。

アニメ一覧の取得(Wikipediaページのparse)

よく考えたらxmlが取得できるのでhtmlなどparseする必要はなかった...

python getDataFromWikipedia.py > animes_2010-2014.txt


 

検索結果の取得

apiにより取得したJSONをファイルに出力する
制限があるため、1秒間に2回、100件ずつ取得する。
また、検索結果が1700件以上あっても仕様上1700件までしか取得できない。

流れとしては以下の通り

  1. 取得対象名がタイトル/説明文/タグのいずれかに含まれているものを取得
  2. 検索結果として得られた動画に付いているタグをJSON形式で100件取得する。
  3. 100件をファイルに保存する

関係無い動画が取得される可能性はありますが、今回はそれもそのアニメ自体の影響力の強さと考えて特にフィルターをかけたりはしていません。

while read line;do;python getSearchResult.py $line;done < animes_2010-2014.txt

 

JSON→tsv 変換処理

変換処理によって横列がタグの出現回数, 縦列がコンテンツとするtsvファイルを作成する。

python tagParseJSON.py animes > animes_tag.tsv


変換処理によって832*354,117のデータが得られた


 

tSNEによる可視化

python mds_plot.py animes_tag.tsv
手法とパラメーターの探索

http://raw.cordea.jp/niconico/act1/explore_1.png


確認して一番良さげなPCA+t-SNEに絞る。

  1. PCAによる次元縮約
  2. t-SNEによる座標算出
  3. プロット


http://raw.cordea.jp/niconico/act1/explore_3.png



ココらへんのimageは全てこちらにあります。

結果

小さい画像
f:id:CORDEA:20141126221336p:plain


大きい画像
約33*33inchの非常に大きな画像ですのでお気をつけ下さい。


 

Hierachical clusteringによる可視化

Dendrogramを描きますが、これに関してはRの方が楽なのでRでやります。
ですがこのままプロットしたところで確認できるようなものにならないのは分かりきっているので、ctcライブラリを使用してDendroscope用のデータを作成します。
ちなみにctcライブラリはFedora 20で上手くインストール出来なかったのでこの部分はDebianを使っています。





出来上がったnewick.txtには以下のように何故かダブルクォーテーションが付いていてエラーを吐いたのでダブルクォーテーションを消します。

"(TIGER:82.6491092539521,(Fate%slZero:16.5373639856817,(Free!:18.3057504854552,
(Angel_Beats!:72.6269302031301,(STEINS%scGATE:69.8680393971481,
(R-15:31.1784166447384,(WORKING!!:46.0964574970961,(TARI_TARI:23.1396305160703,

[中略]

72.6269302031301):18.3057504854552):16.5373639856817):82.6491092539521);"

 

Dendroscopeで確認

ラベル一つ一つまで確認できるようなイメージを作成しようとしたところ、Debianでは強制終了し、WindowsではBusy状態で停止したため、適当な大きさで妥協した。

小さい画像

f:id:CORDEA:20141126221246p:plain



大きい画像
こちらも非常に大きな画像ですのでお気をつけ下さい。

 

まとめ

  • アニメ間の距離は続編が近い傾向にある。しかし続編間の距離が非常に遠くなったものもあった。
  • 動画数が非常に少ないアニメが2~3割あると見られ、それらが正常にプロットされておらず、何らかの閾値を設ける必要がある。
  • 説明変数が多すぎて上手くクラスタが構成されない
    • 次元縮約を行わない場合に、次元の呪いによる球面集中現象が見られた

そして結果をまとめるのが一番大変だった...
結果については色々と考察したのですが、やはり変数が多すぎることと手順に問題があること(距離の算出とか)から、検索数などでフィルターをかけて距離の算出法を見直せば何か見えてくるかもしれません。
いずれにしろかなりやりがいのあるデータですので今後も進めてまいります。

 

optparseでエスケープ文字を受け取りたい時

optparseはエスケープ文字をそのまま入力すると期待した結果と異なる挙動を示すことがあります。
これは一部のコマンド(sortなど)にも言えます。
しばらくしたら忘れてそうなのでメモ。

試しに次のようなプログラムを書いてみました。

from optparse import OptionParser

def optSettings():
    usage="hogehoge"
    version="0.0.1"
    parser = OptionParser(usage=usage, version=version)

    parser.add_option(
            "-a",
            action = "store",
            type   = "str",
            dest   = "test"
            )

    return parser.parse_args()

if __name__ == '__main__':
    options, args = optSettings()
    print >>>,options.test


このプログラムで次のように実行すれば"hogehoge"が帰ってきます。

% python optparse_test.py -a "hogehoge"
>>> hogehoge

'\t'や'\n'はこうなります。

% python optparse_test.py  -a "\t"
>>> \t


'\t'の場合は次のような入力によってタブを出力できます。
'#'はわかりやすいように入れているだけです。

% python optparse_test.py  -a $'#\t#'
>>> #	#


ちなみに始めに書いたsortコマンドの場合はこんな感じで。

% sort -t $'\t' -k 2 -nr

おわり。

Pythonで行/列名付きのmatrixを出力するいくつかの方法

正攻法, 変わり種など4つ。

  • 2014/11/12 追記

 方法3に問題が合ったので修正いたしました。
 それと方法4を追加。

 

今回出力したいのはこのようなマトリクス

	Ile	Val	Leu	Phe	Cys	Met	Ala	Gly	Thr	Trp	Ser	Tyr	Pro	His	Asp	Glu	Asn	Gln	Lys	Arg
Ile	IleIle	IleVal	IleLeu	IlePhe	IleCys	IleMet	IleAla	IleGly	IleThr	IleTrp	IleSer	IleTyr	IlePro	IleHis	IleAsp	IleGlu	IleAsn	IleGln	IleLys	IleArg
Val	ValIle	ValVal	ValLeu	ValPhe	ValCys	ValMet	ValAla	ValGly	ValThr	ValTrp	ValSer	ValTyr	ValPro	ValHis	ValAsp	ValGlu	ValAsn	ValGln	ValLys	ValArg
Leu	LeuIle	LeuVal	LeuLeu	LeuPhe	LeuCys	LeuMet	LeuAla	LeuGly	LeuThr	LeuTrp	LeuSer	LeuTyr	LeuPro	LeuHis	LeuAsp	LeuGlu	LeuAsn	LeuGln	LeuLys	LeuArg
Phe	PheIle	PheVal	PheLeu	PhePhe	PheCys	PheMet	PheAla	PheGly	PheThr	PheTrp	PheSer	PheTyr	PhePro	PheHis	PheAsp	PheGlu	PheAsn	PheGln	PheLys	PheArg
Cys	CysIle	CysVal	CysLeu	CysPhe	CysCys	CysMet	CysAla	CysGly	CysThr	CysTrp	CysSer	CysTyr	CysPro	CysHis	CysAsp	CysGlu	CysAsn	CysGln	CysLys	CysArg
Met	MetIle	MetVal	MetLeu	MetPhe	MetCys	MetMet	MetAla	MetGly	MetThr	MetTrp	MetSer	MetTyr	MetPro	MetHis	MetAsp	MetGlu	MetAsn	MetGln	MetLys	MetArg
Ala	AlaIle	AlaVal	AlaLeu	AlaPhe	AlaCys	AlaMet	AlaAla	AlaGly	AlaThr	AlaTrp	AlaSer	AlaTyr	AlaPro	AlaHis	AlaAsp	AlaGlu	AlaAsn	AlaGln	AlaLys	AlaArg
Gly	GlyIle	GlyVal	GlyLeu	GlyPhe	GlyCys	GlyMet	GlyAla	GlyGly	GlyThr	GlyTrp	GlySer	GlyTyr	GlyPro	GlyHis	GlyAsp	GlyGlu	GlyAsn	GlyGln	GlyLys	GlyArg
Thr	ThrIle	ThrVal	ThrLeu	ThrPhe	ThrCys	ThrMet	ThrAla	ThrGly	ThrThr	ThrTrp	ThrSer	ThrTyr	ThrPro	ThrHis	ThrAsp	ThrGlu	ThrAsn	ThrGln	ThrLys	ThrArg
Trp	TrpIle	TrpVal	TrpLeu	TrpPhe	TrpCys	TrpMet	TrpAla	TrpGly	TrpThr	TrpTrp	TrpSer	TrpTyr	TrpPro	TrpHis	TrpAsp	TrpGlu	TrpAsn	TrpGln	TrpLys	TrpArg
Ser	SerIle	SerVal	SerLeu	SerPhe	SerCys	SerMet	SerAla	SerGly	SerThr	SerTrp	SerSer	SerTyr	SerPro	SerHis	SerAsp	SerGlu	SerAsn	SerGln	SerLys	SerArg
Tyr	TyrIle	TyrVal	TyrLeu	TyrPhe	TyrCys	TyrMet	TyrAla	TyrGly	TyrThr	TyrTrp	TyrSer	TyrTyr	TyrPro	TyrHis	TyrAsp	TyrGlu	TyrAsn	TyrGln	TyrLys	TyrArg
Pro	ProIle	ProVal	ProLeu	ProPhe	ProCys	ProMet	ProAla	ProGly	ProThr	ProTrp	ProSer	ProTyr	ProPro	ProHis	ProAsp	ProGlu	ProAsn	ProGln	ProLys	ProArg
His	HisIle	HisVal	HisLeu	HisPhe	HisCys	HisMet	HisAla	HisGly	HisThr	HisTrp	HisSer	HisTyr	HisPro	HisHis	HisAsp	HisGlu	HisAsn	HisGln	HisLys	HisArg
Asp	AspIle	AspVal	AspLeu	AspPhe	AspCys	AspMet	AspAla	AspGly	AspThr	AspTrp	AspSer	AspTyr	AspPro	AspHis	AspAsp	AspGlu	AspAsn	AspGln	AspLys	AspArg
Glu	GluIle	GluVal	GluLeu	GluPhe	GluCys	GluMet	GluAla	GluGly	GluThr	GluTrp	GluSer	GluTyr	GluPro	GluHis	GluAsp	GluGlu	GluAsn	GluGln	GluLys	GluArg
Asn	AsnIle	AsnVal	AsnLeu	AsnPhe	AsnCys	AsnMet	AsnAla	AsnGly	AsnThr	AsnTrp	AsnSer	AsnTyr	AsnPro	AsnHis	AsnAsp	AsnGlu	AsnAsn	AsnGln	AsnLys	AsnArg
Gln	GlnIle	GlnVal	GlnLeu	GlnPhe	GlnCys	GlnMet	GlnAla	GlnGly	GlnThr	GlnTrp	GlnSer	GlnTyr	GlnPro	GlnHis	GlnAsp	GlnGlu	GlnAsn	GlnGln	GlnLys	GlnArg
Lys	LysIle	LysVal	LysLeu	LysPhe	LysCys	LysMet	LysAla	LysGly	LysThr	LysTrp	LysSer	LysTyr	LysPro	LysHis	LysAsp	LysGlu	LysAsn	LysGln	LysLys	LysArg
Arg	ArgIle	ArgVal	ArgLeu	ArgPhe	ArgCys	ArgMet	ArgAla	ArgGly	ArgThr	ArgTrp	ArgSer	ArgTyr	ArgPro	ArgHis	ArgAsp	ArgGlu	ArgAsn	ArgGln	ArgLys	ArgArg


 

方法1: 大人しくnumpy使う


正攻法 (numpy入ってる人にとっては)。

import numpy as np

Aminos = ["Ile", "Val", "Leu", "Phe", "Cys", "Met", "Ala", "Gly", "Thr", "Trp", "Ser", "Tyr", "Pro", "His", "Asp", "Glu", "Asn", "Gln", "Lys", "Arg"]

data = [[a1+a2 for a2 in Aminos] for a1 in Aminos]
with open("matrix.txt", "w") as f:
        f.write("\t" + "\t".join(Aminos) + "\n")
        np.savetxt(f, np.hstack([zip(Aminos), data]), fmt='%s', delimiter="\t")

 

方法2: とりあえずprintしてawkに投げる


awkに馴染みがあれば、まぁ楽といえば楽か

Aminos = ["Ile", "Val", "Leu", "Phe", "Cys", "Met", "Ala", "Gly", "Thr", "Trp", "Ser", "Tyr", "Pro", "His", "Asp", "Glu", "Asn", "Gln", "Lys", "Arg"]
print
for a1 in Aminos:
    print a1
for a1 in Aminos:
    print a1
    for a2 in Aminos:
        print a1+a2
% python matrix_test.py | awk 'BEGIN{c=1}{if(c%21 == 0){print $0}else{printf $0"\t"};c++}' > matrix.txt

方法3: printによる出力


見た目上は出来てるが実際は出来てない方法、とその解決方法。

Aminos = ["Ile", "Val", "Leu", "Phe", "Cys", "Met", "Ala", "Gly", "Thr", "Trp", "Ser", "Tyr", "Pro", "His", "Asp", "Glu", "Asn", "Gln", "Lys", "Arg"]

print "\t",
for a1 in Aminos:
    if Aminos[-1] == a1:
        print "%s\n" % a1,
    else:
        print "%s\t" % a1,
for a1 in Aminos:
    print "%s\t" % a1,
    for a2 in Aminos:
        if Aminos[-1] == a2:
            print "%s\n" % (a1+a2),
        else:
            print "%s\t" % (a1+a2),
問題点1

なぜ問題かは次のようにすれば分かる

for i in range(10):
    print "#",
% python print_test.py
# # # # # # # # # #

つまりprint,には改行コードの代わりに空白が入る。
これでは見かけは出来ていても再利用する際に空白とタブの混在でsplitが面倒になる。

これはPython3系であれば

for i in range(10):
    print("#", end="")

Python2系の場合は

import sys
for i in range(10):
    sys.stdout.write("#")

とすることで解消できる。

 

問題点2

今回の場合は出来ているが、listは重複を許すので

for a1 in Aminos:
    if Aminos[-1] == a1:
        print "%s\n" % a1,
    else:
        print "%s\t" % a1,

ではなく

for i in range(len(Aminos)):
    if len(Aminos) == i+1:
        print "%s\n" % Aminos[i],
    else:
        print "%s\t" % Aminos[i],

の方が確実かと。

方法4: 普通にwrite

Aminos = ["Ile", "Val", "Leu", "Phe", "Cys", "Met", "Ala", "Gly", "Thr", "Trp", "Ser", "Tyr", "Pro", "His", "Asp", "Glu", "Asn", "Gln", "Lys", "Arg"]

with open("matrix.txt", "w") as f:
    f.write("\t")
    for i in range(len(Aminos)):
        if len(Aminos) == i+1:
            f.write("%s\n" % Aminos[i])
        else:
            f.write("%s\t" % Aminos[i])
    for j in range(len(Aminos)):
        f.write("%s\t" % Aminos[j])
        for i in range(len(Aminos)):
            if len(Aminos) == i+1:
                f.write("%s\n" % (Aminos[j]+Aminos[i]))
            else:
                f.write("%s\t" % (Aminos[j]+Aminos[i]))

 

参考


How to print in Python without newline or space? - Stack Overflow

【Fedora 20】erlangのinstallに失敗する

% sudo yum install -y erlang

.
.
.

失敗:
  erlang-erts.x86_64 0:R16B-03.7.fc20                                                                   

完了しました!
% erl
zsh: command not found: erl

selinux-policyをupdateする必要があるらしい

sudo yum update -y selinux-policy


失敗したerlang-ertsだけ再インストール

sudo yum install -y erlang-erts

【JavaScript】地図上の任意の位置に円グラフを表示する

こんな感じで円グラフを表示する方法です。

http://www.cdc.gov/dhdsp/data_statistics/ems/images/mt_pers_type.jpg

http://www.cdc.gov/dhdsp/data_statistics/ems/fs_ems_mt.htm

作ってみて、とりあえず楽にカスタムできそうなやつが出来たのでコードをおいておきます。
結果としてはこんな感じ

jVectorMap and Raphaël - CodePen


Raphaëlは初めて使いましたがこれはいいですね、いじってて楽しいのでもう少し触ってみようかと思います。


 
コードなどは私のCodePenにあります。
今回は単純にこうできる、という紹介ですのであまりそれっぽくないですが...
外枠を太くしたり、といったことがg.Raphaelのpiechartに見た感じなさそうだったので大きさの同じcircleを作成してそれをアニメーションさせています。

あと、gridは座標が分かりやすいようつけているだけです。
 

使用ライブラリ, Version等