隗より始めよ

今後はいろいろ考え始めます。

Pythonの可視化ライブラリDashで作ったグラフをherokuにあげて共有する

Heroku Advent Calendar 20187日目の記事です。

PythonDashという可視化ライブラリがあります。ウェブアプリの形で作られてよいのと、すごい綺麗にグラフがでてきて、しかも物凄い複雑なことが簡単にできて良いライブラリです。詳しくはギャラリーをご覧ください

しかし、いざ共有となり、サーバーに上げてという段階となったときに、ウェブを全く触ったことのない私。どうやったらええんや状態になりました。VPSは契約しているが、色々読んでいるとめんどくさいことこの上なさそうで、ちょっとやりたくないなぁと思いました。しかし、ローカルでだけ動かしているなんて宝の持ち腐れ感しかありません。

そんなときに、Dashのドキュメントをつらつら読んでいると、deploymentのところにherokuを使えば簡単さ的なことが書いてました。ちょうどyコンビネータを読んでherokuに関心があった私。早速試してみることにしました。

その結果は・・・最後まで見てほしいですが、超簡単にアップできたので、VPSを解約してherokuへの乗り換えを考えています。

その前に

gitとheroku CLIが必要となります。

devcenter.heroku.com

書いているとおりにインストールしましょう。

アプリケーションを作りローカルで動かしましょう

ローカルで動いたら、まぁ大丈夫ですが、ちょっとコードを足す必要があります。

herokuで動かそう

さてここからが本番です。といっても先程のDashのdeploymentのページに書いているとおりですが。

①ファイルの設定

まず動かしたいファイルの名前をapp.pyにします。これ以外の名前で動かしたらエラーになったので、他の名前で動かしたい場合何が設定の変更がいるのかもしれません。とりあえず、動かしたいだけなので、app.pyで行きます。

ポイントとなるのはapp.pyファイルにimport osとserver = app.serverを付け加えておくことです。

これをファイルに入力していないと動きませんでした。

②.gitignoreファイルを作ります。

あんまりわかってないのでパスでお願いします。

③Procfileファイルを作る

ドキュメント通り。

web: gunicorn app:server

④requirements.txtファイルを作る

ドキュメントはpip freezeでrequirements.txtを作っていますが、あいにく私はAnacondaを使っているので、地味に自分で入力しました。

dash 
dash-core-components
dash-html-components
plotly 
pandas
numpy
gunicorn
lxml

⑤herokuをイニシャライズして、ファイルをgitにaddし、デプロイします。

$ heroku create my-dash-kyoto #1
$ git add .
$ git commit -m 'hogehoge'
$ git push heroku master
$ heroku ps: scale web:1

これでうまく行くと、https://my-dash-kyoto.herokuapp.comでアプリが動きます。簡単!

⑥ファイルを更新した場合

またファイルなどをアップデートした場合、以下のように再デプロイすると同じアドレスで動きます。

$ git status
$ git add .
$ git commit -m 'kaetayo'
$ git push heroku master

herokuに上げたアプリ

今回は京都市の出しているオープンデータを使って京都の宿泊施設情報を可視化してみました。

横にあるlegendを押すとその押した年代のマーカーが消えるようになっています。2010年を押すと、多くのマーカーが消えるのが面白いですね。それもそのはず、ここ3年で京都の宿泊所数は3倍に増えているようですwインバウンドすごい。私も乗りたかったなぁ・・・

f:id:mazarimono:20181205215309g:plain

アプリはここから見られます

pythonのコードは以下のようになっています。<==矢印部分がherokuで動かす際に必要なおまじないです。

import pandas as pd 
import numpy as np 
import dash 
import dash_core_components as dcc
import dash_html_components as html 
import plotly.graph_objs as go

import os   <==== 付け加え

df = pd.read_csv('kyoto_hotel_comp1.csv', index_col=0)
mapbox_access_token = "mtoTQ"
app = dash.Dash(__name__)

server = app.server    <==== 付け加え

app.layout = html.Div(children=[
    html.H1(children="Kyoto Hotel Map"),

    dcc.Graph(
        id = 'kyoto-hotels',
        figure = {
            'data':[
                go.Scattermapbox(
                lat = df[df['age']== i]['ido'],
                lon = df[df['age']== i]['keido'],
                mode = 'markers',
                marker = dict(
                    size=9
                ),
                text = df[df['age']== i]['hotel_name'],
                name = str(i),
                ) for i in df['age'].unique()
            ],
            'layout':
                go.Layout(
                    autosize=True,
                    hovermode='closest',
                    mapbox = dict(
                        accesstoken=mapbox_access_token,
                        bearing = 0,
                        center = dict(
                            lat=np.mean(df['ido']),
                            lon=np.mean(df['keido'])
                        ),
                        pitch = 90,
                        zoom=10,
                    ),
                    height=600
                )
        }
    )

])

if __name__=='__main__':
    app.run_server(debug=True)