pygal.Pie()のへろわるど、てほどでもない何者か

ぎゃるがどーした、こえてぱおんのかコラ。

COVID-19騒ぎには見える化ようぜの追記として書いたんだけど、やっぱり独立したネタとしても書いといたほうがいいかと思って。pygal の話ね。「人口比 (3?)」で書いたことを繰り返しておく:

「良い見える化を共有すべし、いまや小学生でも実現できるほどに容易なのだからなおさら」てのが、一連の話の主題の半分だった、てことはいい?

そうなんだけれど、実際問題 matplotlib はさすがに多少多めの鍛錬が必要で、さすがにそこいらの一般人が初見で怯んでしまう程度には難解なのは問題で、そういう意味で、ワタシの主張を弱めてしまう理由にもなっている。

「matplotlib だから」である、これは。matplotlib の名前の由来はおそらく「matrix plotting library」であろう。これからわかるように、最初に念頭に置かれたのは「行列の可視化」であり、すなわち「NumPy/SciPyとセットで」使われることが前提になっている。となると、これはもうユーザの層が自ずと偏ってきて、つまり「科学技術系」(特に自然科学系)に属する学者や技術者が好むものとなった。「難しいのが当たり前」の世界にいるもんだから、matplotlib に対しても「もっと簡単にすべきだ」なんて流れにはならん気がする。実際ワタシ自身も結構そっち寄り。

で、「ワタシには matplotlib があるのでおk (あるいは R とか gnuplot でもいい)」で思考停止状態だったとも言えるけれど、今回このようなシリーズを書いた手前、ちったぁ「もっと誰にでも」ネタがあればいいなぁ、とは思っていたの。そんなタイミングで、たまたま glances の(optional な)依存パッケージであるところの「pygal」に気付いた。おそらく WEB ベース前提のプロジェクトと思われる。

一つには結構古参でなおかつ、「WEBで」の方向性が SVG である点は、「いまどきの HTML5 時代」にはそぐわないのかもしれんけれど、いやまぁ、なにせ簡単だ、これは

ワタシにとって初見なので、ほんとにチラ見しかしていない印象としては、「簡単さが非常に特筆すべき特徴だが、それだけ、にも見える」て感じ。あんまり自由度はなさそうなのよね。けど、かなり簡単だこれは。

とりあえず手始めに、Pie:

pygal が必要。なお、面倒なので Python 2.7 対応はしてない。
 1 # -*- coding: utf-8 -*-
 2 import io
 3 import csv
 4 import datetime
 5 import numpy as np
 6 import pygal
 7 
 8 
 9 def _viz(fn):
10     reader = csv.reader(io.open(fn, encoding="utf-8-sig"))
11     next(reader)
12     date = None
13     ag = []
14     mat = None
15     for line in reader:
16         # year,month,date, age_group, tested_positive, hospitalized, serious, death
17         date = datetime.date(*map(int, line[:3]))
18         ag.append(line[3])
19         row = list(map(int, line[4:]))
20         if mat is None:
21             mat = np.array(row)
22         else:
23             mat = np.vstack((mat, np.array(row)))
24     #
25     ser = ["tested_positive", "hospitalized", "serious", "death"]
26     for i in range(len(ser)):    
27         chart = pygal.Pie()
28         chart.title = "{} ({})".format(ser[i], date)
29         for j in range(len(ag)):
30             chart.add(ag[j], mat[j,i])
31         #chart.render_to_file("demography_{}_{}.svg".format(date, ser[i]))
32         print("""<div id='demography_{}_{}'><embed type='image/svg+xml' src='{}'/></div>""".format(
33             date, ser[i], chart.render_data_uri()
34         ))
35 
36 
37 if __name__ == '__main__':
38     #2021-03-30変更 BEG ---毎度お取り寄せると迷惑なので少し大人しくするように書き換えた。
39     #import urllib.request
40     #cont, msg = urllib.request.urlretrieve(
41     #    "https://toyokeizai.net/sp/visual/tko/covid19/csv/demography.csv")
42     #_viz(cont)
43     import urllib.request
44     import shutil
45     if os.path.exists("prefectures.csv"):
46         ctm = datetime.datetime.utcfromtimestamp(os.stat("prefectures.csv").st_mtime)
47         now = datetime.datetime.utcnow()
48         if (now - ctm).total_seconds() > 60 * 60:
49             os.remove("prefectures.csv")
50     if not os.path.exists("prefectures.csv"):
51         cont, msg = urllib.request.urlretrieve(
52             "https://toyokeizai.net/sp/visual/tko/covid19/csv/prefectures.csv")
53         shutil.move(cont, "prefectures.csv")
54     _viz("prefectures.csv")
55     #2021-03-30変更 END

得られた html の断片をここにぺろっと貼り付け(「東洋経済オンライン「新型コロナウイルス 国内感染の状況」」を加工):

「これなら小学生でも出来る」と言えるかどうかは、今の場合 pygal の使い方よりは numpy 依存部分がネックになってむつかしいのかもしらんけれど、少なくとも平均レベルの人が「少しだけ努力すれば」さすがにこれは「簡単だぜ」と言っても支障ないかと。

とにかく「わかりやすく訴えかける」ことが求められてるんだと思うわけな。そしてマスコミは「政府は~をわかりやすく示せ」と要求ばかり言っとらんと、「お前がやればいいし、出来るやろ、それが仕事なんだし」と言いたいわけで、そしてそのための基礎となってるのが、「ほらね、簡単でしょ」の技術的な部分。ただまぁ「ほらね、簡単でしょ」は pygal に関しては「出力が SVG でいい場合に限る」点はネックといえばネック。まぁほかの何か見つけたら、気が向く限りは都度紹介していこうかと思う。