PlotlyExpressどの程度使えるものなのか?私なりに検証してみた。

この記事の目的

EDA(探索的データ解析)を行う際PlotlyExpressが「どんなケースで使用することができるのか?」について私なりに検証してみました。

PlotlyExpressとは?

plotlyのラッパーになります。 plotlyとはオープンソースインタラクティブなデータ可視化ツールです。 Python, R, javascript言語対応です。 ラインセンスはMIT。

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")

f:id:kobakenkken:20191217235907p:plain

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")

f:id:kobakenkken:20191218000305p:plain

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)

f:id:kobakenkken:20191218000423p:plain

まとめと反省

基本的にplotly_expressを中心に用い、plotly_expressで出来ない場合や時間を要する場合はplotlyや他のライブラリを使用するのが楽かなと感じました。

反省:言い訳になるのですが、結婚式や家族での出来事など怒涛の一か月で準備が全然時間とれませんでした。来年はきちんと締め切り守ります。よろしくお願いいたします。

参考

qiita.com

qiita.com