streamlit入門 データ可視化

Streamlit入門 - 基本的な使い方

2022年1月29日

今回はStreamlitというWebアプリ・ダッシュボードを非常に簡単に作成するPythonライブラリについて解説したいと思います。

Pythonを使ったWebアプリ開発のためのフレームワークと言えばDjangoやFlask、ダッシュボードだとこのサイトでも紹介しているDashというツールが代表的です。

これらと比較したStreamlitの特徴は、とにかく速く簡単に動くアプリを作ることができる点です。

JavaScriptはもちろんHTMLやCSSの知識すら不要です。

データサイエンティストにとって、この3つを学んだり使ったりせずにダッシュボードを作れるのはすごく嬉しいのではないでしょうか。(もちろん、HTMLなどを学ぶことはスキルアップになりますし、楽しいことではありますが)

このサイトで紹介しているPython Plotlyで作成したグラフを扱うことができるので、Plotlyでインタラクティブできめ細かい設定をしたグラフを作成し、Streamlitで表示することで、高性能なダッシュボードを作成することができます。

では、どのようにしてWebアプリを作ることができるか見ていきましょう。

Streamlitとは

streamlitとはPythonをベースとしたWebアプリの開発フレームワークです。

コンセプトは『とにかく速く、簡単にWebアプリを作ってデプロイするフレームワーク』です。

しかもPlotlyユーザには嬉しいことに、Plotlyを使ったグラフ作成にも対応しています。

公式ホームページはこちらです。

https://streamlit.io/

現状のstreamlitのメリット・デメリットを一言ずつで言うと、以下のようになります。

メリット:非常に簡単に素早くダッシュボードを作成することができる
デメリット:細かな設定ができない

ですので、Streamlitは比較的簡単なダッシュボードやプロトタイプを作成するに向いていると言えます。

では、今回はStreamlitの基本的な使い方や、テキスト、表、グラフの表示方法について見ていきたいと思います。

今後、スライダーなどで制御する方法や、レイアウトの設定、デプロイの方法について解説していきたいと思います。

Streamlitの基本的な使い方

基本的な使い方を見ていきましょう。

まずはStreamlitをインストールします。

pip install streamlit

そして、空のpythonファイルを作成し、pythonファイル内でモジュールをインポートしましょう。

import streamlit as st

そのあとに色々とコードを書いていきますが、それは次の章からにしたいと思います。

先に動かし方ですが、.pyファイルを作成してstreamlitで表示するには、ターミナルで以下のコマンドを入力します。

streamlit run .pyファイル名

例えば、app.pyというファイルに作成したのであれば、ターミナルで以下のようなコマンドを実行します。

streamlit run app.py

すると次のような表示がでると思います。

このLocal URLの部分をクリックする、もしくはブラウザに直接入力することでブラウザ上に作ったプログラムが表示されます。

では、ここからはテキストの表示方法を見ていきましょう。

こちらのAPIリファレンスページに色々と載っていますので、ごちらも参考にしてみてください。

API reference

テキストを表示する

タイトルを表示:title

タイトルの形式で表示します。

st.titleにタイトルとして設定したい文字列を渡すだけです。

st.title('タイトル')

結果はあとでまとめて見たいと思います。

ヘッダを表示:header

ヘッダを表示します。

st.header('ヘッダを表示')

サブヘッダを表示:subheader

少し小さいヘッダを表示します。

st.subheader('サブヘッダを表示')

小さなキャプションを表示:caption

小さな文字を表示します。

st.caption('キャプションを表示')

では、ここまでを書いた結果を見てみましょう。

実行は以下のコマンドで行います。

streamlit run app.py

以下のように表示されます。

HTMLのタグは一切なく書けてしまいますね。

では続きを見てみましょう。

Markdown

Markdownはキレイな文書を作成する上で非常に便利な表記法になります。

Markdownの詳しい説明はここでは省略しますので、以下の記事などを参考にしてみてください。

Qiita Markdown 書き方 まとめ

Markdown形式で文字列を設定し、st.markdownに渡すだけです。

markdown = """ 
# タイトル
## ヘッダ 
以下の数式にしたがって計算する関数を作成する.  
$$y = 2x$$  
  
Pythonコード
```python
def forward(x):
    return 2 * x
```
"""
st.markdown(markdown)

最後の行まではMarkdown形式で表示させたいテキストを作成しています。

#は一番大きな見出しで、##は次に大きな見出しです。

そして、Latexの数式やPythonのコードを混ぜています。

最後にst.markdownを呼び出すことにより、以下のように表示されます。

何でも表示可能:st.write

ここで、オールマイティなst.writeを見てみましょう。

st.writeは渡されたデータにより出力形式を自動で設定してくれる優れものです。

例えば、streamlitにはpandasのDataFrameを表形式で表示したり、マークダウンを表示するためのメソッドがそれぞれ用意されていますが、そんなことを気にせずst.writeを使えばstreamlitがうまくやってくれます。

以下のコードで、通常の文字列、DataFrame、Markdownを使って表示してみましょう。

dfという変数には株価の時系列情報が入っています。

st.title('何でも使えるst.write')
st.write('悩み:直近7日間の株価テーブルを表示したいなぁ…')
markdown = """
### st.writeでデータフレームを表形式で表示できます!
以下のコードでpandasのデータフレームをそのまま表にすることが可能です。
```python
st.write(df.head(7))
```
結果はこちら↓
"""
st.write(markdown)
st.write(df.head(7))

すると以下のような表示になります。

すごく便利ですね。

では、st.writeでも良いですが、プログラムならプログラム、Latexの数式であればLatexを使う方法も見ておきます。

プログラムコードを表示:code

プログラムを表示します。

st.codeで表示しますが、一つ目の引数が表示したいコード、二つ目の引数がプログラミング言語になっており、デフォルトは"python"になっています。

次のようなコードになります。

st.write('Pythonのコード')
st.code('def hoge(self):')
st.write('HTMLのコード')
st.code('<div>HTML形式</div>', language='html')

すると以下のように表示されます。

Latexを表示:latex

あまり使わないかもしれませんが、Texを使って数式を書くこともできます。

st.latexで数式を渡します。

st.write('幾何ブラウン運動')
st.latex('S_{t+1}=S_{t}\exp(\mu \Delta_t+\sigma \sqrt{\Delta_t}\epsilon_t)')

キレイな数式を描くことができますね。

表を表示する

では、テキスト情報を出力する方法は大体わかりましたので、次は表を表示しましょう。

インタラクティブな表を表示する:st.dataframe

pandasのデータフレームをそのまま渡して、列をクリックすることで並び替えができるようなインタラクティブな表を表示することができます。

widthとheightで幅、高さを変更できます。

st.dataframe(df, width=None, height=500)

こんな感じでソートしたりスクロールしたりすることができます。

(日付のインデックスをもう少しきれいにした方が良さそうですね)

静的な表を表示する:st.table

次はインタラクティブではなく、静的な表を表示します。

st.write('直近7日間の株価推移(静的なテーブル)')
st.table(df.iloc[:7])

指標を表示する:st.metric

ダッシュボードを作成する際には非常に効果的な指標を表示する方法です。

st.metricを呼び出します。

引数は以下です。

  • label
    その指標のラベルを表示します。株価や感染者数などですね。
  • value
    表示したい値です。
  • delta=None
    前日比などの変化幅等を表示します。デフォルトはNoneなので何も指定しなければ表示されません。
  • delta_color="normal"
    normalを指定すると、プラスであれば緑色、マイナスであれば赤色でdeltaで指定された数値を表示します。
    reverseを指定すると色が逆になり、offを指定すると色を変えません。
    デフォルトはnormalです。

では以下のようなコードで株価と株価の前日比を表示しましょう。

st.subheader(f'12/31の{name}の株価')
st.metric(label='株価', value=f'{value} 円', delta=f'{delta} 円')

次のように、よく見かけるような表示方法になります。

複数表示

続いて複数を表示する方法を見ておきます。

st.columnsで列を分割します。

引数で分割する個数を指定することができます(リストで幅を指定しながら分割することも可能ですが、それは次回にしたいと思います)。

ここでは、3つに分けて表示したいと思います。

names = ['スノーピーク', '楽天', 'トヨタ']
num_columns = len(names)
st.subheader('12/31の株価')
cols = st.columns(num_columns)
for name, col in zip(names, cols):
    value = df.iloc[0][name]
    delta = df.iloc[0][name] - df.iloc[1][name]
    col.metric(label=name, value=f'{value} 円', delta=f'{delta} 円')

次のように3社の株価を横に並べて表示することができます。

グラフを表示する

やはりダッシュボードにはグラフが必要ですので、最後にグラフを表示したいと思います。

線グラフ:line_chart

まず基本的な線グラフです。

st.line_chartで作成できます。

引数は、width、heightで幅や高さを設定できます。

ただし、use_container_width=Trueであれば画像を列のサイズに自動的に合わせるので、これをFalseにすることで幅を調節できるようになります。

df = df[names]
st.subheader('2021年の株価推移')
st.line_chart(df)

以下のようなグラフになりますが、静的なグラフではなくインタラクティブなグラフになっています。

ただし、細かい設定はできないので、細かく制御したい場合は後述するplotlyと組み合わせる方法が良いです。

エリア・チャート:area_chart

エリアチャートも簡単でst.area_chartを呼び出すだけです。

引数も線グラフのline_chartと同じです。

以下のコードでエリアチャートが作成できます。

(エリア・チャートにする意味のない内容ですが…)

st.subheader('2021年の株価推移')
st.area_chart(df)

一応こんな感じになります。

皆さんは適切なグラフを選んでください。

棒グラフ:bar_chart

続いて、棒グラフです。

こちらもbar_chartを呼び出すだけです。

width、heightで幅や高さを設定することができます。

df_returnは3社の1年間のリターンが入っています。

st.subheader('2021年の株価変化率の比較')
st.bar_chart(df_return)

以下のような棒グラフができますが、あまりキレイではないですね。

散布図

散布図については現在使えないようです(違ったらすみません)。

streamlitで散布図を表示したい場合は次のpyplotでMatplotlibで作成した図を使用するか、plotly_chartでplotlyで作成した図を表示する必要があります。

plotly_chartを使えば、以下のように散布図を表示させることができます。

やり方はあとで説明しています。

Matplotlib:st.pyplot

今までのグラフは非常に簡単ですが、細かい設定は全くできないので、自由度が高いMatplotlibを使って表示したいと思います。

Matplotlibでグラフを作成し、それをst.pyplotに渡すだけです。

例えば、色を少し変えたい場合です。

(それにしても日本語が対応していないのが面倒くさいですね。確か1行でうまくできたと思いますが、わざわざ面倒です…)

fig, ax = plt.subplots()
ax.bar(x=['Snowpeak', 'Rakuten', 'Toyota'], height=df_return[names],
       color='green', width=0.6, alpha=0.6)
st.subheader('2021年の株価変化率の比較')
st.pyplot(fig)

Plotlyで作成したグラフを表示する:st.plotly_chart

Plotlyはインタラクティブなグラフを作成するためのライブラリです。

個人的にすごくおすすめなので、このサイトでも詳しく紹介しています。

Matplotlibのときと同じように、plotlyでグラフを作成し、Figureオブジェクトを引数としてst.plotly_chartに渡します。

ちょっとコードが長くなってしまいますが、ほとんどがグラフ自体を作成するところで、streamlitでグラフを表示するところは最後の1行だけです。

fig = go.Figure()
fig.add_traces(go.Bar(x=names,
                      y=df_return[names],
                      marker_color=['royalblue', 'lightgrey', 'lightgrey'],
                      width=0.4,
                      text=[f'{value:0.1%}' for _, value in df_return.iteritems()],
                      textposition='outside',
                      textfont=dict(size=24, color=['royalblue', 'lightgrey', 'lightgrey'])
                ))
fig.update_layout(plot_bgcolor='white',
                  xaxis=dict(tickfont_color='grey',
                             showline=True,
                             linewidth=1,
                             linecolor='lightgrey'),
                  yaxis=dict(range=(0, max(df_return)*1.15),
                             visible=False),
                             width=800
)

st.subheader('2021年の株価変化率の比較')
st.plotly_chart(fig)

以下のように対象企業を強調することもできるので便利ですね。コロナ渦でキャンプ用品のメーカーであるスノーピークの株価が突出して上昇しています。

線グラフも同様にplotly_chartにFigureオブジェクトを渡すだけで作成できます。

fig = go.Figure()
fig.add_traces(go.Scatter(x=df.index,
                          y=df['スノーピーク'],
                          marker_color='royalblue',
                          line_width=3,
                          name='スノーピーク')
                )
fig.add_traces(go.Scatter(x=df.index,
                          y=df['楽天'],
                          line_width=3,
                          marker_color='lightgrey',
                          name='楽天')
                )
fig.update_layout(plot_bgcolor='white',
                  legend=dict(x=0.02, y=0.9, 
                              orientation='h'),
                  xaxis=dict(tickfont_color='grey',
                             showline=True,
                             linewidth=1,
                             linecolor='lightgrey'),
                  yaxis=dict(tickfont_color='grey',
                             showline=True,
                             linewidth=1,
                             linecolor='lightgrey'),
)

st.subheader('2021年の株価推移の比較')
st.plotly_chart(fig)

これで本格的なグラフを使った便利なダッシュボードを作ることができそうですね。

(ご参考) Streamlitを学ぶことができるUdemy講座

最後にStreamlitを学ぶことができる講座を2つご紹介しておきます。

『爆速で5つのPython Webアプリを開発』

軽快なテンポで、非常にわかりやすく、楽しく学ぶことができると思います。

APIを使うことにより、テキストから音声生成をしたり、Youtubeのデータを使用したりと色々な応用例を学ぶことができます。


『Streamlit, Pandas, Pythonで学ぶ!データ分析の基礎とインタラクティブダッシュボード作成入門』

オープンデータである一人あたり賃金データを使って、集計やStreamlitを使った可視化を行います。

データサイエンティストを目指している人、実際にデータ分析をしたい人にはオススメです。

まとめ

今回はStreamlitの基本的な使い方を解説しました。

非常に簡単にダッシュボードを作成できることを感じていただけたと思います。

分析した結果をこういったダッシュボードで表示してプレゼンテーションをしてみては如何でしょうか?

次はコントロールを使った制御についてです↓

もし他の機能も興味があれば、以下の記事で一通りの機能をまとめて紹介していますので、気になる記事がないかご確認ください!

おまけ

こちらのVIEWという転職サイトアプリですが、AIを使ったキャリア診断、キャリア・シミュレーションができるということで使ってみましたが、すごく面白いです。

VIEWS 若手ハイクラス向け転職

「本や論文などで学習することが好きである」や「データや数字を扱うことが得意である」というのはかなり当てはまりますね。

提案された企業も、なるほどね~という感じでした。

想定年収も思ったより高くてびっくりです。

転職してもいいかな~と思う今日この頃です。

では!!

-streamlit入門, データ可視化
-,