PlotlyExpressどの程度使えるものなのか?私なりに検証してみた。
この記事の目的
EDA(探索的データ解析)を行う際PlotlyExpressが「どんなケースで使用することができるのか?」について私なりに検証してみました。
PlotlyExpressとは?
plotlyのラッパーになります。 plotlyとはオープンソースでインタラクティブなデータ可視化ツールです。 Python, R, javascript言語対応です。 ラインセンスはMIT。
- 公式サイト: https://plot.ly/python/plotly-express/
- API Ref: https://www.plotly.express/plotly_express/#plotly_express.line
- Github : https://github.com/plotly/plotly.py
PlotlyExpressとPlotlyの違いはどこ?PlotlyExpressにメリットがあるのか?
散布図と箱ひげ図をそれぞれで出力してみて比較してみた。
import 関係
import plotly.offline as offline import plotly.graph_objs as go import pandas as pd
google colabeでplotlyを表示するための処理
import plotly # google colab内で実行するには以下関数の実行が必要 def configure_plotly_browser_state(): import IPython display(IPython.core.display.HTML(''' <script src="/static/components/requirejs/require.js"></script> <script> requirejs.config({ paths: { base: '/static/base', plotly: 'https://cdn.plot.ly/plotly-latest.min.js?noext', }, }); </script> ''')) configure_plotly_browser_state() # jupyter notebookで表示する際に使う plotly.offline.init_notebook_mode(connected=False)
データセット読み込み
import pybaseball as pb # MLB Advanced Mediaからデータを抜くためのID key = pb.playerid_lookup("Syndergaard", "Noah")["key_mlbam"].values[0] # データがpandas.DataFrameで返ってきます data = pb.statcast_pitcher("2015-01-01", "2019-12-31", key) # データ整形 # 投球日・イニング・投球数でソート data = data.sort_values(["game_date", "inning", "at_bat_number", "pitch_number"]) # 球種データがNaNの場合は行ドロップ data = data.dropna(subset=['pitch_type']) data["seq"] = data.reset_index().index
比較1:散布図
plotly_expressの場合=3行
import plotly_express as px configure_plotly_browser_state() px.scatter(data, x="seq", y="release_speed", color="pitch_type")
plotlyの場合=だいたい21行
"pitch_type"の種類を把握する
data["pitch_type"][~data["pitch_type"].duplicated()] 11725 FF 11722 CU 11718 SI 11717 CH 11708 IN 11003 SL 10931 FT 8467 PO Name: pitch_type, dtype: object
FF_df = data[data["pitch_type"] == "FF"] CU_df = data[data["pitch_type"] == "CU"] SI_df = data[data["pitch_type"] == "SI"] CH_df = data[data["pitch_type"] == "CH"] IN_df = data[data["pitch_type"] == "IN"] SL_df = data[data["pitch_type"] == "SL"] FT_df = data[data["pitch_type"] == "FT"] PO_df = data[data["pitch_type"] == "PO"] trace = go.Scatter( x = FF_df["seq"], y = FF_df["release_speed"], name='FF', mode = "markers" ) trace1 = go.Scatter( x = SI_df["seq"], y = SI_df["release_speed"], name='SI', mode = "markers" ) trace2 = go.Scatter( x = CH_df["seq"], y = CH_df["release_speed"], name='CH', mode = "markers" ) trace3 = go.Scatter( x = IN_df["seq"], y = IN_df["release_speed"], name='IN', mode = "markers" ) trace4 = go.Scatter( x = SL_df["seq"], y = SL_df["release_speed"], name='CU', mode = "markers" ) trace5 = go.Scatter( x = FT_df["seq"], y = FT_df["release_speed"], name='FT', mode = "markers" ) trace6 = go.Scatter( x = PO_df["seq"], y = PO_df["release_speed"], name='PO', mode = "markers" ) layout = go.Layout( xaxis=dict(title='seq'), yaxis=dict(title='release_speed'), showlegend=False) fig = dict(data=[trace, trace1, trace2, trace3, trace4, trace5, trace6], layout=layout) # グラフを描画 configure_plotly_browser_state() plotly.offline.iplot(fig)
比較2 箱ひげ図
plotly_expressの場合:約2行
configure_plotly_browser_state() px.box(data, x="pitch_type", y="release_speed")
plotlyの場合:約9行
fig = go.Figure() fig.add_trace(go.Box( y = FF_df["release_speed"], name='FF' )) fig.add_trace(go.Box( y = SI_df["release_speed"], name='SI' )) fig.add_trace(go.Box( y = CH_df["release_speed"], name='CH' )) fig.add_trace(go.Box( y = IN_df["release_speed"], name='IN' )) fig.add_trace(go.Box( y = SL_df["release_speed"], name='CU' )) fig.add_trace(go.Box( y = FT_df["release_speed"], name='FT' )) fig.add_trace(go.Box( y = PO_df["release_speed"], name='PO' )) # グラフを描画 configure_plotly_browser_state() plotly.offline.iplot(fig)
まとめと反省
基本的にplotly_expressを中心に用い、plotly_expressで出来ない場合や時間を要する場合はplotlyや他のライブラリを使用するのが楽かなと感じました。
反省:言い訳になるのですが、結婚式や家族での出来事など怒涛の一か月で準備が全然時間とれませんでした。来年はきちんと締め切り守ります。よろしくお願いいたします。