最初に結果です。下のようにGitHub StarのトレンドをBokehで可視化してはてなブログに埋め込む方法を解説します。マウスオーバーしてもらうとtooltipが表示される(=画像埋め込みでない)ことが確認していただけると思います。
既存のサイトでもリポジトリ名を入れると可視化してくれるサイトがいくつかあるのですが、細かい見た目を調整したかったため自分でスクリプトを書いてみました。コード全体はGitHubに上がっています。
GitHub Star取得
まずGitHub Starを取得します。GitHub APIのList Stargazersを使います。
注意点として日時を取得するためにヘッダーにAccept: application/vnd.github.v3.star+json
をつけてGitHub API v3を使う必要があります。下がコード例です。
user = "dask" repo = "dask" url = f"https://api.github.com/repos/{user}/{repo}/stargazers" token = os.environ["GITHUB_TOKEN"] headers = { "Accept": "application/vnd.github.v3.star+json", "Authorization": f"token {token}" } resps = [] while True: resp = requests.get(url, headers=headers) resps.extend(resp.json()) if "next" in resp.links: url = resp.links['next']['url'] else: break
データ加工
取得した情報をpandasを使って加工していきます。時系列のグルーピングにはdt
アクセサを使っています。もし詳しく知りたい方はsinhrksさんのブログを参照してください。
df = pd.DataFrame(resps) df['dt'] = pd.to_datetime(df['starred_at']) df_counts = df.groupby(df['dt'].dt.date).size().to_frame("count").reset_index() df_counts['cumsum'] = df_counts['count'].cumsum()
Bokehでの可視化
Bokehで可視化します。ポイントが2種類あります。
figure
にsizing_mode='scale_width'
を指定して幅をブログに動的に合わせるbokeh.embed.components
でHTML全体でなく該当箇所のdivを書き出す
詳しくは以下のコードを参考にしてください。
source = ColumnDataSource(data=df_counts) colors = Paired[3] p = figure( plot_height=300, toolbar_location=None, tooltips=None, y_range=(df_counts['cumsum'].min(), df_counts['cumsum'].max()*1.05), x_axis_type="datetime", background_fill_color=colors[0], background_fill_alpha=.1, border_fill_color=colors[0], border_fill_alpha=.1, sizing_mode='scale_width', title=f"{user}/{repo}のGitHubスター数の遷移" ) # 線グラフ p.line( x='dt', y='cumsum', color=colors[1], line_width=5, legend="累計", source=source ) # 増加数 p.extra_y_ranges = {"second": Range1d(start=df_counts['count'].min(), end=s.quantile(0.99))} p.add_layout(LinearAxis(y_range_name="second"), 'right') p.vbar( x='dt', top='count', width=1, y_range_name="second", color=colors[2], alpha=.6, legend="1日ごと", source=source ) # グラフの見た目を調整 p.axis.minor_tick_line_color = None p.grid.visible = None p.title.align = "center" hover = HoverTool( tooltips=[("日付", "@dt{%F}"), ("累計", "@cumsum"), ("1日ごと", "@count")], formatters={"dt": 'datetime'}, mode='vline' ) p.add_tools(hover) p.legend.location = "top_left" # 埋め込み用のhtml, jsを取得 script, plot_div = components(p) # ファイルに書き出す with open(f"{user}_{repo}.html", mode="w") as f: f.write(plot_div + script)
はてなブログ埋め込み
書き出せたら、はてなブログに埋め込みます。はてなブログはJS埋め込みに対応しているので、そのまま埋め込むことができます。
先程書き出したHTML+JSに追加でBokehのクライアントJSライブラリをCDNから読み込む必要があるので、下のコードを追加してください。
<script type="text/javascript" src="https://cdn.pydata.org/bokeh/release/bokeh-1.3.4.min.js"></script>
詳しくはBokehのドキュメントを参照してください。(ただし、CDNのリンクが間違っているのは注意)
これで上記のようなグラフを貼り付けることができました。
さいごに
最近Bokehの便利さと描画のキレイさに感銘を受けてmatplotlibから移行しつつあります。今後もBokeh関連のエントリを書いていけたら、と思っています。
※JSが動かなかった場合に備えて念の為画像も貼っておきます。