Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

plotly express が使えるシチュエーションまとめ【matplotlibより使えるときはどんなとき?】

はじめに

グラフの描画といえばmatplotlib + serbornがメジャーですよね。
これらを超えるポテンシャルを秘めたのがインタラクティブなグラフが作成可能なplotly express。
plotly expressを使うとmatplotlib + seabornよりも便利な点に焦点を当てて紹介したいと思います。

plotly express、あまり癖がない印象です。plotlyと比較して行数少なくグラフがプロットでき、matplotlibを使ったことがある方はあまり違和感なく導入できると思います。

個人的に考えるplotly expressが役に立つシーンはこんな感じです。
- ヒストグラム書いたけど右に裾が広すぎていまいちよくわからん...かといって右裾だけを拡大したグラフ書くのもなんかかっこ悪い。
- 積み上げ棒グラフ作りたいけど数が少ないやつ潰れてしまう。てかそもそもseabornで積み上げグラフめんどい。
- 散布図で外れているデータを確認したいけど、どのデータが外れているデータなのか探すのが面倒。
- ペアプロットしたけど説明変数が多すぎる...もっと一発でどの説明変数が重要なのか確かめる方法ないのか~
- 時系列データで異常が出ているときの時刻や値が知りたい。

この記事でやること

seabornと比較して便利なグラフをプロットしてみます分析データとしてpythonのデータセットのなかからtitanicのデータ、年度ごとの乗客数のデータ、ワインの等級のデータを使います。

titanicデータで
- ヒストグラム
- 積み上げ棒グラフ
- 箱ひげ図
飛行機乗客数データで
- 折れ線グラフ
ワインの等級データで
- 散布図
- 並行座標

これらのグラフについて実際のhtmlファイルへのリンクも載せました。htmlリンクからでは実際にぐりぐり動かす感じを味わえます。気持ちいいです。
例えばこちらのグラフとか。
https://nakanakana12.github.io/plotly/hello_world/histgram.html

様々なグラフの書き方はこちらの記事がめちゃくちゃ詳しいです。
令和時代のPython作図ライブラリのデファクトスタンダードPlotlyExpressの基本的な描き方まとめ https://qiita.com/hanon/items/d8cbe25aa8f3a9347b0b

ライブラリのインポート

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import plotly.express as px
from sklearn.datasets import load_wine

titanicのデータ

df = pd.read_csv('http://biostat.mc.vanderbilt.edu/wiki/pub/Main/DataSets/titanic3.csv')
#年齢を10歳ごとに丸めた列を追加
df["age10"] = df["age"] // 10 * 10
df["survived_num"] = df["survived"]
df["survived"] = df["survived"].replace(1,"alive").replace(0,"dead")
df["sex_num"] = df["sex"].replace("female",1).replace("male",0)
df = df.reset_index()
df.head()

image.png

ヒストグラム

右に裾が長い分布に対してはplotlyが便利!

運賃(fare)のヒストグラムを表示します。生存したかどうか(survived)で色分けしました。
運賃は正規分布となっておらず、右側に裾が長い分布となっています。
こういうときって、matplotlibだと数が少ないデータがみづらくなってけっこう困りますよね。

plotlyなら少ないところを拡大できるので様子をつかみやすいです。

今回の場合、運賃が高い人は数は少ないけど生存率が高いのが一つのグラフをぐりぐりするだけでわかりました。

fig = px.histogram(df, x="fare", color="survived",nbins=200, opacity=0.4, marginal="box"
                  , title="Survivedごとの運賃のヒストグラム")
fig.update_layout(barmode='overlay')
fig.show()

# htmlで保存
fig.write_html('./histogram.html', auto_open=False)

image.png

htmlファイルはこちら。グリグリ動かせます。
https://nakanakana12.github.io/plotly/hello_world/histgram.html

積み上げ棒グラフ

plotly expressなら積み上げ棒グラフが簡単で見やすい!

これが一番のおすすめかもしれないです。

積み上げ棒グラフをつくったとき困るのが、分類が多いときですよね。
数の少ないものの数がわからなかったりします。
plotlyなら数が少なくてもカーソルを合わせれば数が確認できるのは便利ですね。

ここでは年齢ごとの生存したかどうかを可視化しました。また、性別をまとめて表示した場合とグラフを分けた場合のものをつくってみました。
50代以降は生存率が低くなっていることや、女性の方が生存率が高いのが上手に可視化されていますね。

#前処理
df_bar = df.groupby(["survived", "age10","sex"],as_index=False).size().reset_index(drop=True)
df_bar.columns = ["survived", "age10","sex","count"]
df_bar.head()

image.png

fig = px.bar(df_bar, y="age10", x="count", orientation="h",color="survived"
            , title="年齢ごとのsurvived(まとめて表示)")
fig.show()

image.png
htmlファイルはこちら。
https://nakanakana12.github.io/plotly/hello_world/bar.html

fig = px.bar(df_bar, y="age10", x="count", orientation="h",facet_row="sex",color="survived"
            , title="年齢ごとのsurvived")
fig.show()

image.png

htmlファイルはこちら。
https://nakanakana12.github.io/plotly/hello_world/bar3.html

箱ひげ図

外れ値の確認が簡単!

箱ひげ図の場合、外れ値や信頼区間のデータを簡単に確認できるのが便利です。

また、個人的に便利だと思うのがhover_dataをindexに指定することです。
こうすることで外れ値のindexを簡単に確認でき、その他の列のデータもすぐに確認できます。

fig = px.box(df, x="pclass", y="age", color="survived", hover_data=["index"])
fig.show()

# htmlで保存
fig.write_html('./box.html', auto_open=False)

image.png

htmlファイルはこちら。
https://nakanakana12.github.io/plotly/hello_world/box.html

飛行機の乗客データ

折れ線グラフ

異常値の時刻や値が簡単にわかる!

時系列データの場合折れ線グラフが定番ですね。乗客数のデータから各月ごとの推移をプロットしてみます。

表示するグラフを凡例をクリックすることで選択できたり、下のスライダーで表示区間を選択できます。
またマウスで気になる点のx軸、y軸を確認することができます。

このデータだと正直恩恵すくないですが、カテゴリが多いときや、異常値をのx軸を確認したいときなどには便利そうです。

df = sns.load_dataset("flights")
fig = px.line(df, x="year", y="passengers", color="month", title="乗客数の推移")
fig.update_layout(xaxis_range=['1949-01-01', '1961-01-01'], # datetime.datetimeで指定してもよい
                 xaxis_rangeslider_visible=True)
fig.show()
# htmlで保存
fig.write_html('./time_series.html', auto_open=False)

image.png

htmlファイルはこちら。
https://nakanakana12.github.io/plotly/hello_world/time_series.html

ワインの等級データ

データの準備

data_wine = load_wine()
df = pd.DataFrame(data_wine["data"], columns=data_wine["feature_names"])
df["target_ID"] = data_wine["target"]
df["target"] = df["target_ID"].replace(0,"bad").replace(1,"good").replace(2,"great")

df["alcohol_rank"] = np.where(df["alcohol"] < df["alcohol"].mean(),"low", "high")
df["flavanoids_rank"] = np.where(df["flavanoids"] < df["flavanoids"].mean(),"low", "high")

df = df.reset_index()
df.head()

image.png

散布図

気になるデータのindexが簡単にわかる!

散布図もマウスをあてることで、どのデータが外れ値なのかを簡単に確認できるのが便利です。

個人的おすすめはhover_dataにindexを指定することですかね。これをすれば、マウスをあてるだけで外れ値のデータのindexがわかり他の値も簡単に確認することができます。

seabornのペアプロットみたいなこともけっこう簡単にできちゃいます。

fig = px.scatter(df, x="alcohol", y="color_intensity", color="target", 
                 marginal_x="box", marginal_y="histogram", trendline="ols",
                 hover_data=["index"],
                title="ワインのアルコール度数と色彩強度の関係")
fig.show()

# htmlで保存
fig.write_html('./scatter.html', auto_open=False)

image.png

htmlファイルはこちら。
https://nakanakana12.github.io/plotly/hello_world/scatter.html

fig = px.scatter_matrix(df, dimensions=["alcohol", "flavanoids","color_intensity","hue"],color="target",
                        hover_data=["index"],
                       title="ワインの説明変数相関分析")
fig.show()

# htmlで保存
fig.write_html('./scatter2.html', auto_open=False)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533584/6c7cc445-d564-a18d-ec97-b54de9d97195.png)


htmlファイルはこちら。
https://nakanakana12.github.io/plotly/hello_world/scatter2.html

並行座標

変数ごとの相関を確認しやすい!!

説明変数が多いときこれはめちゃくちゃ役に立ちそう。

この図を見るとflavanoidsやhueが小さいとき、color_intensityが大きいときにtarget_IDが大きくなるのが一目瞭然ですね。
他の変数の相関もかなりわかりやすい気がします。

カテゴリ化された変数にも使うことができます。

fig = px.parallel_coordinates(df, dimensions=["alcohol","flavanoids", "color_intensity","hue"],color="target_ID")
fig.show()

# htmlで保存
fig.write_html('./parallel.html', auto_open=False)

image.png

htmlファイルはこちら。
https://nakanakana12.github.io/plotly/hello_world/parallel.html

#カテゴリカル変数の場合
fig = px.parallel_categories(df, dimensions=["alcohol_rank","flavanoids_rank","target"],color="target_ID")
fig.show()

# htmlで保存
fig.write_html('./parallel_cat.html', auto_open=False)

image.png

htmlファイルはこちら。
https://nakanakana12.github.io/plotly/hello_world/parallel_cat.html

終わりに

plotly自体は知っていたのですが、使い方に癖があり学習を断念していました。
それに比べるとplotly expressはけっこう簡単に使い始められる感じです。
外れ値の確認作業などがある場合は本当に便利ですね。

3Dの可視化やアニメーションなんかもいつかチャレンジしてみたいです。

最後までお読みいただきありがとうございました。
参考になりましたらLGTMなどしてくれたら励みになります。

kanamun3
ランニング、サプリメント、機械学習が好き。 国立理系の博士卒。 データ分析に関してアウトプット。
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