Help us understand the problem. What is going on with this article?

可視化ツールDashのチュートリアル - Part1: インストール~描画 -

More than 1 year has passed since last update.

はじめに

Dashとは、Python製のWebアプリケーションのフレームワークであり、可視化ツールのPlotlyに従う描画を行うことができます。

この記事は、Dashのチュートリアルを翻訳したものです。

なおDashでの描画にはPlotlyの知識がある程度必要なため、コチラの記事などで復習しておくと理解しやすいです。

インストール

Dashを実行するにはいくつかのライブラリをインストールする必要があります。また開発は現在進行形で行われているので定期的にアップデートしてください。
なおPython2系とPython3系の両方をサポートしています。

pip install dash==0.21.1  # The core dash backend
pip install dash-renderer==0.12.1  # The dash front-end
pip install dash-html-components==0.10.1  # HTML components
pip install dash-core-components==0.22.1  # Supercharged components
pip install plotly --upgrade  # Plotly graphing library used in examples

Dashを使って描画を行う

DashでHTMLを生成する

Dashアプリの構成は以下の2つになります。

  • layout: HTMLの外観を決める
  • interactivity: アプリとデータ操作の連携をとる

実際に棒グラフを描画するHTMLを生成してみましょう。

import dash
import dash_core_components as dcc
import dash_html_components as html

必要なライブラリをインポートします。
dash_core_componentsは、グラフやボタン、ドロップダウンなどのUIを提供しています。
dash_html_componentsは、HTMLのDivタグやH1タグなどを提供しています。

次にアプリの外観を決めましょう。

# アプリの宣言
app = dash.Dash()

# HTMLの外観を定義
app.layout = html.Div(children=[
    # <H1>タグ
    html.H1(children="Hello Dash"),

    # <div>タグ
    html.Div(children="""
    Dash: A web application framework for Python
    """),

    dcc.Graph(
        id="examplr-graph",
        figure={
            "data": [
                 {"x":[1,2,3], "y":[4,1,2], "type":"bar", "name":"SF"},
                 {"x":[1,2,3], "y":[2,4,5], "type":"bar", "name":"Montreal"}
            ],
            "layout": {
                "title": "Dash Data Visualization"
            }
        }
    )
])

上のコードでは、まず初めにHTML.Divを定義し、その中にさらにHTMLタグを作成していることがわかります。

dcc.Graphの部分でPlotlyに従う図を作成するので、データを渡し方もPlotlyの際と同様に辞書型で渡す必要があることに注意しましょう。

ではアプリを起動してみます。

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

以上のコードを実行すると以下のような図がブラウザーに表示されます。

01.png

ここで引数のchildrenは、慣例として一番初めの引数として指定され、children=は省略することが可能です。

HTML:応用

dash_html_componentsライブラリでは、1つ1つのHTMLタグに辞書型でクラスを指定することができます。

import dash
import dash_core_components as dcc
import dash_html_components as html

app = dash.Dash()

# 背景色とテキストの色を設定
colors = {
    "background": "#111111",
    "text": "#7FDBFF"
}

app.layout = html.Div([
    html.H1(
        children="Hello Dash",
        # ここでスタイルを設定(辞書型で渡す)
        style={
            "textAlign": "center",
            "color": colors["text"]
        }
    ),
    # <h1 style="text-align: center; color: #7FDFF">Hello Dash</h1>

    html.Div(
         children='Dash: A web application framework for Python.', 
         # ここでスタイルを設定(辞書型で渡す)
         style={
             'textAlign': 'center',
             'color': colors['text']
         }
    ),
    # <div style="text-align: center; color: #7FDFF">Dash: A web application framework for Python.</div>

    dcc.Graph(
        id='example-graph-2',
        figure={
            'data': [
                {'x': [1, 2, 3], 'y': [4, 1, 2], 'type': 'bar', 'name': 'SF'},
                {'x': [1, 2, 3], 'y': [2, 4, 5], 'type': 'bar', 'name': 'Montréal'},
            ],
            'layout': {
                'plot_bgcolor': colors['background'],
                'paper_bgcolor': colors['background'],
                'font': {
                    'color': colors['text']
                }
            }
        }
    )
])

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

02.png

このときstyleの指定にはキャメルケース(text-alignではなくtextAlign)であることに注意しましょう。

表を作成する

Pandasのデータフレームから表を生成する。

import dash
import dash_core_components as dcc
import dash_html_components as html
import pandas as pd

df = pd.read_csv(
    'https://gist.githubusercontent.com/chriddyp/'
    'c78bf172206ce24f77d6363a2d754b59/raw/'
    'c353e8ef842413cae56ae3920b8fd78468aa4cb2/'
    'usa-agricultural-exports-2011.csv')

このデータフレームは以下のようになります。

03.png

このデータをHTMLの表へ変換するための関数を定義します。

def generate_table(dataframe, max_row=10):
    return HTML.Table(
        # Header
        [html.Tr([html.Th(col) for col in dataframe.columns])] +

        # Body
        [html.Tr([
            html.Td(dataframe.iloc[i][col]) for col in dataframe.columns
        ]) for i in range(min(len(dataframe), max_rows))]
    )

そしてアプリの外観を設定し起動します。

app = dash.Dash()

app.layout = html.Div(children=[
    html.H4(children='US Agriculture Exports (2011)'),
    generate_table(df)
])

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

以上を実行すると以下の図が得られます。

04.png

複雑な可視化を行う

dash_core_componentsにはGraphと呼ばれるコンポーネントが存在し、Ploylyの35種類以上の図に対応しています。(Plotlyの公式HP)

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

app = dash.Dash()

df = pd.read_csv(
    'https://gist.githubusercontent.com/chriddyp/' +
    '5d1ea79569ed194d432e56108a04d188/raw/' +
    'a9f9e8076b837d541398e999dcbac2b2826a81f8/'+
    'gdp-life-exp-2007.csv')

このデータフレームは以下のようになります。

05.png

それでは大陸でグループ分けを行い、それぞれの国のデータを可視化してみましょう。

app.layout = html.Div([
    dcc.Graph(
        id='life-exp-vs-gdp',
        figure={
            'data': [
                go.Scatter(
                    # 1人当たりGDP
                    x=df[df['continent'] == i]['gdp per capita'],
                    # 寿命
                    y=df[df['continent'] == i]['life expectancy'],
                    text=df[df['continent'] == i]['country'],
                    mode='markers',
                    opacity=0.7,
                    marker={
                        'size': 15,
                        'line': {'width': 0.5, 'color': 'white'}
                    },
                    name=i
                # 大陸ごとのデータを抽出する。
                ) for i in df.continent.unique()
            ],
            'layout': go.Layout(
                # x軸はログスケール
                xaxis={'type': 'log', 'title': 'GDP Per Capita'},
                yaxis={'title': 'Life Expectancy'},
                # left, bottom, top, right
                margin={'l': 40, 'b': 40, 't': 10, 'r': 10},
                legend={'x': 0, 'y': 1},
                hovermode='closest'
            )
        }
    )
])

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

06_r2.gif

Markdownを使用する

import dash
import dash_core_components as dcc
import dash_html_components as html

app = dash.Dash()

markdown_text = '''
### Dash and Markdown

Dash apps can be written in Markdown.
Dash uses the [CommonMark](http://commonmark.org/)
specification of Markdown.
Check out their [60 Second Markdown Tutorial](http://commonmark.org/help/)
if this is your first introduction to Markdown!
'''

app.layout = html.Div([
    dcc.Markdown(children=markdown_text)
])

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

07.png

他のdash_core_componentsを試す

dash_core_componentsには、Graph以外にもドロップダウンやマークダウン、テキストボックスなど様々なオプションが存在します。

import dash
import dash_core_components as dcc
import dash_html_components as html

app = dash.Dash()

app.layout = html.Div([
    html.Label('Dropdown'),
    dcc.Dropdown(
        options=[
            {'label': 'New York City', 'value': 'NYC'},
            {'label': u'Montréal', 'value': 'MTL'},
            {'label': 'San Francisco', 'value': 'SF'}
        ],
        # ここに選択した値が入る(ここではデフォルト値を設定している)
        value='MTL'
    ),

    html.Label('Multi-Select Dropdown'),
    dcc.Dropdown(
        options=[
            {'label': 'New York City', 'value': 'NYC'},
            {'label': u'Montréal', 'value': 'MTL'},
            {'label': 'San Francisco', 'value': 'SF'}
        ],
        value=['MTL', 'SF'],
        # 複数の選択を可能にする引数
        multi=True
    ),

    html.Label('Radio Items'),
    dcc.RadioItems(
        options=[
            {'label': 'New York City', 'value': 'NYC'},
            {'label': u'Montréal', 'value': 'MTL'},
            {'label': 'San Francisco', 'value': 'SF'}
        ],
        value='MTL'
    ),

    html.Label('Checkboxes'),
    dcc.Checklist(
        options=[
            {'label': 'New York City', 'value': 'NYC'},
            {'label': u'Montréal', 'value': 'MTL'},
            {'label': 'San Francisco', 'value': 'SF'}
        ],
        # リスト型で与えていることに注意
        values=['MTL', 'SF']
    ),

    html.Label('Text Input'),
    dcc.Input(value='MTL', type='text'),

    html.Label('Slider'),
    dcc.Slider(
        min=0,
        max=9,
        marks={i: 'Label {}'.format(i) if i == 1 else str(i) for i in range(1, 6)},
        value=5,
    ),
# 表示を2列に分けるstyleを設定
], style={'columnCount': 2})

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

08.gif

困ったときは

それぞれの引数など何かわからないことがあった場合は、help関数を使いましょう。

help(dcc.Dropdown)

終わりに

以上がDashを使用してグラフをHTMLに描画する方法です。
どんな図を出力するにしても

  • layout
  • interactivity

の2つを設定することが基本です。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away