隗より始めよ

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

Dashを使ってみた

f:id:mazarimono:20180829082210j:plain

証券会社とか四季報のチャートを使ってたのですが、思いの外使いにくいというのと、自分で加工したデータを見るのになんかよいツールがないかと思っていたところDashってのがあるということを知り、この三連休はDashをいじっていました。

普通にチャートを作るだけだと簡単だったんですが、ドロップダウンとか使うと、途端に初心者にはよく分からなくなりました。

しかし、それはただ単にお手本のコードを完コピしておけばよかったのですが、ぼけていたのか、こんなものいらんやろと思ったのか、リストでデータを作っているところをリストにしていなかったということなだけでした。

でもそのおかげでコールバックの中身を調べたりと、色々と面白いことができてよかったです。

完成作品

f:id:mazarimono:20181008212908g:plain

仮想通貨の線のチャートを描くものですが、銘柄をドロップダウンで選択するとチャートが追加されます。そして、チャートの期間の設定もできます。

チャートが追加されるのは、ギャラリーを見てカッコいいなと思い、ソースを見ながら作ったものの、データの指定を間違っていたり、リストにデータを入れなかったりと、凡ミスが続いたせいで作るのに二日もかかりました。

url: https://dash-stock-tickers.plot.ly/
source: github.com

ソースを見てグラフはループで回して作って、ドロップダウンをマルチにしたら良いのか―、超簡単とか思ってたら、別のところではまって時間をたくさん取られました。そのときの注意点を書いておきます。

ドロップダウンの初期設定は[]でくくっておく

app.layout = html.Div([
                dcc.Dropdown(
                        id = 'selector',
                        options = [{'label': i, 'value': i} for i in df.name.unique()],
                        value = ['bitcoin'],
                        multi = True
                        ),

ドロップダウンのところは上のようなコートになっているのですが、valueのところが最初に選択されている値となります。

さっきのリンク先のお手本では[]でくくってあったのですが、二つあるしかなーとか思って、'bitcoin'にしてたら、この後のループのところで死んだ。なかなか理由は分からなかったが、ここだった。今は反省している

コールバックの二つ目の指定がよく分からん・・・

@app.callback(
    dash.dependencies.Output('three-graph', 'children'),
    [dash.dependencies.Input('selector', 'value'),
    dash.dependencies.Input('date-picker', 'start_date'),
    dash.dependencies.Input('date-picker', 'end_date')])

選択したものをチャートとかに返す部分があるのです。この場合一つ目はid(自分でつけたやつ)は分かるんですが、二つ目は何か??ってのがよく分からない。まぁ、失敗していると「こん中から選べや」的にエラーを返してくれるので何とかなったが、いまだになんだかよく分かりません。でもこれで動いたし今は分かったつもりになっている///

グラフのデータもちゃんと[]でくくるのだ

for i, factor in enumerate(factors):
            dff = df[df['name'] == factor].sort_values('Date')
            dff.index = dff['Date']
            dff = dff.loc[start_date: end_date, :]
            linechart = {
        'x': dff['Date'],
        'y': dff['Close'],
        'type': 'line',
        'name': factor
            }

   graphs.append(dcc.Graph(
            id = factor,
        figure = {
        'data': [linechart],
        'layout': {'title': '{}-chart'.format(factor)}}))       

リストにグラフを入れて返すみたいな感じですが、グラフのデータを指定するときに、先に作っていたグラフのデータを[]でくくってデータのところに入れておかないといけませんでした。それをやっていなかったせいでか、チャートは表示されるものの、データが表示されず、何をやっているのか状態になっていました。

終わりに

というような感じで2日がかりで思っていたようなグラフが作れるようになりました。今後は見栄えを考えたり、サーバーにのっけたりということをやるべきですかねー。

そんなことより、まず言いたいのはDash凄いということです。普通にグラフ書くだけだと超簡単だし、今日書いた私が詰まったところも普通の人なら難なくクリアって感じです。サンプルとか見ていると、こんなものが作れるのかとビビります。プレゼンとかでグラフで人々の度肝を抜けそうな。

話を戻すと、サーバーが思いのほか曲者で、flaskのせるのに今現在苦戦中だったり、https化に動かすライブラリみたいなのがなんかのライブラリのせいで動かないので、サクラに聞いたらそれは自分で解決しろといわれたり、中々ハードル高いなって感じですが、まぁローカルで動かす分には問題なしなので、その辺は来週の休みにでもと思ったりしますが、https化は自分で使う分には問題ないしなーみたいに思ったり。

IT初心者には挑むべき壁が多いので面倒なような楽しいような・・・

ザ・プレミアム・モルツ Dash Button

ザ・プレミアム・モルツ Dash Button

import dash 
import dash_core_components as dcc 
import dash_html_components as html 
import pandas as pd 
from datetime import datetime as dt 
import plotly.graph_objs as go 

df = pd.read_csv('three.csv', parse_dates=['Date'])
df = df[['Date', 'Close**', 'name']]
df.columns = ['Date', 'Close', 'name']

external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']

app = dash.Dash(__name__, external_stylesheets=external_stylesheets)

app.layout = html.Div([
                dcc.Dropdown(
                        id = 'selector',
                        options = [{'label': i, 'value': i} for i in df.name.unique()],
                        value = ['bitcoin'],
                        multi = True
                        ),
                dcc.DatePickerRange(
                    id = 'date-picker',
                    start_date = dt(df['Date'].min().year, df['Date'].min().month, df['Date'].min().day),
                    end_date = dt(df['Date'].max().year, df['Date'].max().month, df['Date'].max().day)
                    ),

                    html.Div(id = 'three-graph')
                        
                    ], className='container')

@app.callback(
    dash.dependencies.Output('three-graph', 'children'),
    [dash.dependencies.Input('selector', 'value'),
    dash.dependencies.Input('date-picker', 'start_date'),
    dash.dependencies.Input('date-picker', 'end_date')])
def make_chart(factors, start_date, end_date):
    graphs = []

    if not factors:
        graphs.append(html.H2(
            'Select Cryptocurrency Please!'))
    else:
        for i, factor in enumerate(factors):
            dff = df[df['name'] == factor].sort_values('Date')
            dff.index = dff['Date']
            dff = dff.loc[start_date: end_date, :]
            linechart = {
        'x': dff['Date'],
        'y': dff['Close'],
        'type': 'scatter',
        'name': factor
            }

            graphs.append(dcc.Graph(
            id = factor,
        figure = {
        'data': [linechart],
        'layout': {'title': '{}-chart'.format(factor)}}))

    return graphs

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