Bokeh、Flask、Python 3を使用したレスポンシブ棒グラフ

翻訳者から



最近、Flask + Bokehのpythonダイジェストチュートリアルに出会いました。 このチュートリアルは初心者を対象としています。PythonとHTMLの構文を知っている必要はありません。 これらの例はUbuntu 16.04で動作しますが、Windowsでは、仮想環境での動作が少し異なります。







画像







エントリー



Bokehは強力なオープンソースライブラリであり、JavaScriptで1行も記述せずにWebアプリケーションのデータを視覚化できます。 d3.jsのような視覚化ライブラリを学習することは有用かもしれませんが、問題を解決するために数行のPythonコードを書く方がはるかに簡単です。







Bokehを使用すると、驚くほど詳細なインタラクティブな視覚化や、棒グラフなどの単純なものを作成できます。







FlaskとBokehを使用してWebアプリケーションのデータを視覚化する方法を見てみましょう。







ツール



以下で説明するものはすべてPython 2とPython 3の両方で動作しますが、新しいアプリケーションにはPython 3を使用することをお勧めします。 この記事の執筆時点でPython 3.6.1を使用しました。 Python自体に加えて、次の依存関係が必要になります。









開発環境のセットアップに関する詳細が必要な場合は、 マニュアルを参照してください。 すべてのサンプルコードは、GitHubのMITライセンスで利用できます。







ボケとフラスコの設定



プロジェクトのクリーンな仮想環境を作成します。 原則として、このコマンドは、すべての仮想環境が置かれている別のvenvsフォルダーで実行します。







python3 -m venv barchart
      
      





仮想環境をアクティブにします。







 source barchart/bin/activate
      
      





仮想環境をアクティブ化すると、コマンドプロンプトが変わります。

画像

アプリケーションを起動する新しいターミナルウィンドウごとに仮想環境をアクティブにする必要があることを忘れないでください。







これで、作成した仮想環境にBokehとFlaskをインストールできます。 このコマンドを実行して、適切なBokehおよびFlaskバージョンをインストールします。







 pip install bokeh==0.12.5 flask==0.12.2 pandas==0.20.1
      
      





ダウンロードしてインストールすると、必要なライブラリが仮想環境で利用可能になります。 出力をチェックして、すべてがインストールされていることを確認します。







 Installing collected packages: six, requests, PyYAML, python-dateutil, MarkupSafe, Jinja2, numpy, tornado, bokeh, Werkzeug, itsdangerous, click, flask, pytz, pandas Running setup.py install for PyYAML ... done Running setup.py install for MarkupSafe ... done Running setup.py install for tornado ... done Running setup.py install for bokeh ... done Running setup.py install for itsdangerous ... done Successfully installed Jinja2-2.9.6 MarkupSafe-1.0 PyYAML-3.12 Werkzeug-0.12.2 bokeh-0.12.5 click-6.7 flask-0.12.2 itsdangerous-0.24 numpy-1.12.1 pandas-0.20.1 python-dateutil-2.6.0 pytz-2017.2 requests-2.14.2 six-1.10.0 tornado-4.5.1
      
      





これで、アプリケーションに直接アクセスできます。







Flaskでのアプリケーションの実行



シンプルなFlaskアプリケーションを作成し、ページに棒グラフを追加します。 次の内容のapp.py



ファイルを使用して、プロジェクトのフォルダーを作成します。







 from flask import Flask, render_template app = Flask(__name__) @app.route("/<int:bars_count>/") def chart(bars_count): if bars_count <= 0: bars_count = 1 return render_template("chart.html", bars_count=bars_count) if __name__ == "__main__": app.run(debug=True)
      
      





これは、 chart



機能を備えたシンプルなFlaskアプリケーションです。 chart



は、描画するデータの量を決定するために後で使用される整数を受け入れます。 chart



内のrender_template



関数は、 Jinja2テンプレートエンジンを使用してHTMLを生成します。







最後の2行では、デバッグモードでポート5000のコンソールからアプリケーションを実行できます。 実稼働環境ではデバッグモードを使用しないでください。これには、WSGIサーバーとGunicornがあります。







プロジェクトフォルダー内にtemplates



フォルダーを作成します。 その中にchart.html



ファイルを作成します。 app.py



chart



関数にはapp.py



、それがないとアプリケーションは正しく動作しません。 chart.html



マークアップを入力します。







 <!DOCTYPE html> <html> <head> <title>Bar charts with Bokeh!</title> </head> <body> <h1>Bugs found over the past {{ bars_count }} days</h1> </body> </html>
      
      





chart.html



は、URLを介してchart



関数に渡される列の数が表示されます。







h1



タグ内のメッセージは、アプリケーションのテーマと一致します。 毎日の自動テストシステムによって検出されたバグの数のグラフを作成します。







これで、アプリケーションをテストできます。







仮想環境がまだアクティブであり、 app.py



があるフォルダーにいることを確認してください。 python



コマンドを使用してapp.py



を起動します。







 $(barchart) python app.py
      
      





localhost:5000/16 /に移動します。 URLを変更すると、大きなメッセージが表示されるはずです。









私たちのアプリケーションはすでに開始されていますが、今のところ印象的ではありません。 スケジュールを追加します。







棒グラフの生成



Bokehを使用するコードを追加するだけです。 app.py



を開き、その上に行を追加します。







 import random from bokeh.models import (HoverTool, FactorRange, Plot, LinearAxis, Grid, Range1d) from bokeh.models.glyphs import VBar from bokeh.plotting import figure from bokeh.charts import Bar from bokeh.embed import components from bokeh.models.sources import ColumnDataSource from flask import Flask, render_template
      
      





ファイルの残りの部分では、Bokehとランダムモジュールを使用して、データと棒グラフを生成します。







グラフのデータは、ページがリロードされるたびに再生成されます。 実際のアプリケーションでは、より信頼性が高く便利なデータソースを使用してください!







app.py



変更をapp.py



インポート後のコードは次のようになります。







 app = Flask(__name__) @app.route("/<int:bars_count>/") def chart(bars_count): if bars_count <= 0: bars_count = 1 data = {"days": [], "bugs": [], "costs": []} for i in range(1, bars_count + 1): data['days'].append(i) data['bugs'].append(random.randint(1,100)) data['costs'].append(random.uniform(1.00, 1000.00)) hover = create_hover_tool() plot = create_bar_chart(data, "Bugs found per day", "days", "bugs", hover) script, div = components(plot) return render_template("chart.html", bars_count=bars_count, the_div=div, the_script=script)
      
      





chart



関数は、ランダムな組み込みモジュールを使用してデータを含むリストを生成します。 chart



create_hover_tool



create_bar_chart



2つの関数を呼び出します。 これらの関数はまだ作成していないため、 chart



関数の後にコードを追加し続けます。







 def create_hover_tool(): #       return None def create_bar_chart(data, title, x_name, y_name, hover_tool=None, width=1200, height=300): """  .     ,   ,       . """ source = ColumnDataSource(data) xdr = FactorRange(factors=data[x_name]) ydr = Range1d(start=0,end=max(data[y_name])*1.5) tools = [] if hover_tool: tools = [hover_tool,] plot = figure(title=title, x_range=xdr, y_range=ydr, plot_width=width, plot_height=height, h_symmetry=False, v_symmetry=False, min_border=0, toolbar_location="above", tools=tools, responsive=True, outline_line_color="#666666") glyph = VBar(x=x_name, top=y_name, bottom=0, width=.8, fill_color="#e12127") plot.add_glyph(source, glyph) xaxis = LinearAxis() yaxis = LinearAxis() plot.add_layout(Grid(dimension=0, ticker=xaxis.ticker)) plot.add_layout(Grid(dimension=1, ticker=yaxis.ticker)) plot.toolbar.logo = None plot.min_border_top = 0 plot.xgrid.grid_line_color = None plot.ygrid.grid_line_color = "#999999" plot.yaxis.axis_label = "Bugs found" plot.ygrid.grid_line_alpha = 0.1 plot.xaxis.axis_label = "Days after app deployment" plot.xaxis.major_label_orientation = 1 return plot
      
      





対処するコードがたくさんあります。 今のところcreate_hover_tool



関数はNoneのみを返します。これまでのところ、ホバーするときにヒントを表示する必要がないからです。







create_bar_chart



関数内で、生成されたデータをColumnDataSource



タイプのオブジェクトに変換します。これは、プロットのためにBokeh関数への入力に渡すことができます。 x軸とy軸の範囲を設定します。







ホバーのヒントを設定するまで、 tools



リストは空です。 すべての魔法は、 figure



関数の呼び出しで発生します。 サイズ、ツールバー、境界線、ブラウザウィンドウのサイズを変更するときのグラフの動作の設定など、グラフの作成に必要なすべてを彼女に提供します。







VBar



クラスを使用して垂直列を作成し、 add_glyph



関数を使用してチャートに追加しますadd_glyph



関数は、データを列に変換する規則を設定します。







最後の2行は、チャートのレイアウトを変更します。 たとえば、 plot.toolbar.logo = None



を使用してBokehロゴを削除し、両方の軸にキャプションを追加しました。 視覚化をカスタマイズする方法を知るために、 bokeh.plottingのドキュメント目の前に置いておくことをお勧めします。







グラフを表示するには、 templates/chart.html



ファイルにいくつかの変更を加えるだけです。 ファイルを開き、その内容を次のものに置き換えます。







 <!DOCTYPE html> <html> <head> <title>Bar charts with Bokeh!</title> <link href="http://cdn.pydata.org/bokeh/release/bokeh-0.12.5.min.css" rel="stylesheet"> <link href="http://cdn.pydata.org/bokeh/release/bokeh-widgets-0.12.0.min.css" rel="stylesheet"> </head> <body> <h1>Bugs found over the past {{ bars_count }} days</h1> {{ the_div|safe }} <script src="http://cdn.pydata.org/bokeh/release/bokeh-0.12.5.min.js"></script> <script src="http://cdn.pydata.org/bokeh/release/bokeh-widgets-0.12.5.min.js"></script> {{ the_script|safe }} </body> </html>
      
      





Bokeh CSSファイルの読み込みには6行のうち2行、スクリプトの読み込みには2行、グラフの生成には2行が必要です。







すべての準備ができました。アプリケーションを確認しましょう。 app.py



への変更を保存すると、Flaskはアプリケーションを自動的にリロードします。 Webサーバーを停止した場合は、 python app.py



して再度起動できます。







ブラウザでlocalhostを開きます:5000/4 /









少し空に見えますが、 / localhost:5000/16 /に移動すると、列数を16に変更できます。









さらに4倍...









それはかなりよさそうだ。 しかし、各列を詳細に調べることができるようにホバーヒントを追加するとどうなりますか? これを行うには、 create_hover_tool



関数を変更します。







ホバーのヒントを追加する



app.py



内で、 create_hover_tool



関数を変更します







 def create_hover_tool(): """Generates the HTML for the Bokeh's hover data tool on our graph.""" hover_html = """ <div> <span class="hover-tooltip">$x</span> </div> <div> <span class="hover-tooltip">@bugs bugs</span> </div> <div> <span class="hover-tooltip">$@costs{0.00}</span> </div> """ return HoverTool(tooltips=hover_html)
      
      





PythonアプリケーションにHTMLを埋め込むのはかなり奇妙に思えるかもしれませんが、これがツールチップのタイプを決定する方法です。 $x



を使用して列のx座標を表示し、 @bugs



bugsを使用してデータソースの「バグ」フィールドを表示し、 $@costs{0.00}



を使用して「costs」フィールドを小数点以下2桁の数値として表示します。







return None



return HoverTool(tooltips=hover_html)



置き換えてください。

ブラウザーに戻り、 localhostページを再読み込みします:5000/128 /









素晴らしい仕事です! URLの列の数で遊んでみて、グラフがどのように見えるかを確認してください。







グラフは約100列で塗りつぶされているように見えますが、任意の値を設定してみてください。 50,000で悲しい画像が得られます。









ええ、一度に数百以上の列を表示するには、何か他のことをする必要があるようです。







次は?



Bokehで素晴らしいグラフィックを作成しました。 次に、配色を変更したり、別のデータソースを接続したり、他の種類のグラフを試したり、大量のデータを表示する方法を見つけたりできます。







Bokehではさらに多くのことができるため、 公式ドキュメントGitHubリポジトリ 、Full Stack PythonのBokehページをご覧ください








All Articles