彷徨うおのこ

死ぬまで死なないぜ おれは

本日のやったこと
クラウドPython開発環境構築(cloud9)
1-1:cloud9ログイン(https://c9.io/)
1-2:プロジェクト作成(GUIで操作)
1-3:仮想環境作成
--------------------------
virtualenvの起動
$ virtualenv my_env
$ source my_env/bin/activate

python2->3の切り替え
$ virtualenv my_env --python=/usr/bin/python3.5
起動時の引数追加でOK
--------------------------
②チャート系のPythonアプリケーション作成
2-1:依存関係のインストール
$ pip install dash dash-renderer dash-html-components dash-core-components plotly

2-2:Hello World作成と起動確認
import dash
import dash_core_components as dcc
import dash_html_components as html

app = dash.Dash()

app.layout = html.Div('hello world')

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

import dash が読み込めない
原因:
app.runserver(flask)でのデフォルトの起動ポートは8080
対して、cloud9でのデフォルトの起動ポートは8050
なので上記コードではポートがずれているのでエラー。

つまり、起動ポートを指定することで解消。
->
if __name__ == '__main__':
    app.run_server(debug=True)
->
if __name__ == '__main__':
    app.run_server(host='0.0.0.0', port=8080)

2-3:グラフの表示
app.layoutの変更_グラフの表示
app.layout = html.Div(children=[
    html.H1('hello world'),
    dcc.Graph(id='example',
              figure ={
                  'data': [{'x': [1,2,3,4,5], 'y': [5,6,7,2,1], 'type': 'line', 'name': 'boats'}]
              })
    ])
結果
OK
app_layoutの変更_グラフの表示②
    dcc.Graph(id='example',
              figure ={
                   'data': [
                      {'x': [1,2,3,4,5], 'y': [5,6,7,2,1], 'type': 'line', 'name': 'boats'},
                      {'x': [1, 2, 3, 4, 5], 'y': [8, 7, 2, 7, 3], 'type': 'bar', 'name': 'Cars'},
                      ],
                    'layout': {
                        'title': 'Basic Dash Graphs'
                        }
                    })
    ])
結果:
OK

2-4:ユーザーインターフェイスの追加
import dash
from dash.dependencies import Input, Output
import dash_core_components as dcc
import dash_html_components as html

app = dash.Dash()

app.layout = html.Div(children=[
    dcc.Input(id='input', value='Enter something', type='text'),
    html.Div(id='output')
    ])

@app.callback(
    Output(component_id='output', component_property='children'),
    [Input(component_id='input', component_property='value')])
def update_value(input_data):
    try:
        return str(float(input_data)**2)
    except:
        return "some error"
        

if __name__ == '__main__':
    app.run_server(host='0.0.0.0', port=8080)
結果:
OK

2-5:ユーザー入力とデータの連携
①依存関係のインストール
$ pip install pandas pandas-datareader

error:pandasインストール時にエラー
-----------------
  File "", line 17, in

  File "/home/ubuntu/workspace/my_env/build/pandas/setup.py", line 736, in

    packages=find_packages(include=['pandas', 'pandas.*']),

TypeError: find_packages() got an unexpected keyword argument 'include'
-----------------
原因:
https://stackoverflow.com/questions/29477456/find-package-errors-during-installing-package-via-pip/29477720
setuptoolsのバージョンが古く、find_packages()include が未定義
なので、以下のコマンドを実行
$ pip install -U setuptools
------------------
error2:pip install pandas実行時のエラー
#warning "Using deprecated NumPy API, disable it by " \
------------------
pandasのようなPythonのC拡張パッケージは独自でインストールされることはなく、
各種のパッケージのバージョンを正しくupgradeさせておく必要がある。
->以下のコマンドを実行
$ pip freeze --local | grep -v '^\-e' | cut -d = -f 1  | xargs pip install -U
------------------
エラー解消:
pip install pandasではなく、easy-install pandasコマンドにてインストール
------------------
import pandas_datareader.data as web
import datetime

start = datetime.datetime(2015,1,1)
end = datetime.datetime(2018,2,8)

df = web.DataReader('TSLA', 'google', start, end)

print(df.head())
-----------------
error:
pandas_datareader.exceptions.ImmediateDeprecationError: 
Google finance has been immediately deprecated due to large breaks in the API without the
introduction of a stable replacement. Pull Requests to re-enable these data
connectors are welcome.

See https://github.com/pydata/pandas-datareader/issues
------------------
原因:
引数の'google'のAPI仕様が変更となり、
fix-yahoo-financeを使用するようになった。

解決策:
'google'を'iex'に変更したらOK
------------------
(my_env)yasutaka_ono:~/workspace $ python dash-demo.py 
               open     high      low    close   volume
date                                                   
2015-01-02  20.0390  20.2494  19.9998  20.1271  1229939
2015-01-05  20.0194  20.0194  19.7844  19.8334  1083137
2015-01-06  20.0292  20.1467  19.7257  19.8236  2209124
2015-01-07  21.1354  21.2431  21.0179  21.0766  2486293
2015-01-08  21.0766  21.1648  21.0179  21.1060  1296471
(my_env)yasutaka_ono:~/workspace $ 
------------------
各種設定の統合
import dash
import dash_core_components as dcc
import dash_html_components as html

import pandas_datareader.data as web
import datetime

start = datetime.datetime(2015,1,1)
end = datetime.datetime.now()

stock = 'SNE'

df = web.DataReader(stock, 'iex', start, end)

app = dash.Dash()

app.layout = html.Div(children=[
    html.H1('ソニーの株価表示'),
    dcc.Graph(id='example',
              figure ={
                   'data': [
                      {'x': df.index, 'y': df.close, 'type': 'line', 'name': stock},
                      ],
                    'layout': {
                        'title': stock
                        }
                    })
    ])

if __name__ == '__main__':
    app.run_server(host='0.0.0.0', port=8080)
結果:
OK
------------------
各種設定の統合②
import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input,Output
import pandas_datareader.data as web
import datetime

app = dash.Dash()

app.layout = html.Div(children=[
    html.Div(children='''
        Symbol Graph:
    '''),
    
    dcc.Input(id='input', value='', type='text'),
    html.Div(id='output-graph')
])

@app.callback(
    Output(component_id='output-graph', component_property='children'),
    [Input(component_id='input', component_property='value')]
    )
def update_graph(input_data):
    start = datetime.datetime(2017,1,1)
    end = datetime.datetime.now()
    df = web.DataReader(input_data, 'iex', start, end)
    
    return dcc.Graph(
        id='example-graph',
        figure={
            'data': [
                {'x': df.index, 'y': df.close, 'type': 'line', 'name': input_data},
            ],
            'layout': {
                'title': input_data
            }
        }
    )

if __name__ == '__main__':
    app.run_server(host='0.0.0.0', port=8080)
-------------------
2-6:情報のライブアップデート機能