Pythonによる対話的なデータ可視化のためのPlotlyライブラリの使用

前回の記事では、Pandasライブラリを使って基本的なプロットや時系列プロットを行う方法について説明しました。

Pandas、Matplotlib、Seabornライブラリは優れたデータプロットライブラリですが、これらは静的なグラフしかプロットすることができません。

静的プロットは、単純な非インタラクティブな画像のようなものです。

多くの場合、静的プロットで十分な情報を伝えることができます。

しかし、場合によっては、プロットにユーザのインタラクティビティを追加したいこともあるでしょう。

この記事では、PythonのPlotlyライブラリを使って、どのようにインタラクティブなプロットを描けるかを見ていきます。

plotly を使って地理的なデータをプロットし、そのようなプロットでユーザーがどのように対話できるかを説明します。

必須ライブラリのインストール

Plotlyのライブラリをpipでインストールするには、以下のコマンドを実行します。

$ pip install plotly


Plotlyに加えて、PandasライブラリとPlotlyの間のコネクタとして動作し、Pandasデータフレームを使用して直接インタラクティブなグラフをプロットすることを支援するCufflinksも使用します。

Cufflinksをpipでインストールするには、以下のスクリプトを実行します。

$ pip install cufflinks


必須ライブラリのインポート

Plotlyは基本的にデータの可視化をホストするオンラインライブラリですが、オフラインでインタラクティブなプロットを描画するために使用できるオフラインデータパッケージも提供されています。

私がスクリプトを実行するために使用しているJupyter notebookでPlotlyを実行する前に、通常通りNumpyとPandasとともにPlotlyとCufflinksの両ライブラリをインポートする必要があります。

以下のスクリプトはNumpyとPandasのライブラリをインポートしています。

import pandas as pd
import numpy as np
%matplotlib inline


次に、この記事で使用するPlotlyモジュールのオフライン版をインポートする必要があります。

以下のスクリプトがそれを行います。

from plotly.offline import download_plotlyjs, init_notebook_mode, plot, iplot


スクリプトを実行する前に、JavaScriptとノートブックを接続する必要があります。

Plotlyのプロットはインタラクティブなので、裏側でJavaScriptを使用します。

これから実行するスクリプトは、Jupyter notebookで実行されます。

Jupyter notebookとJavaScriptを接続するためには、以下のスクリプトを実行する必要があります。

init_notebook_mode(connected=True)


最後に、Cufflinkライブラリをインポートし、オフラインで使用することを確認する必要があります。

そのために、以下のスクリプトを実行します。

import cufflinks as cf
cf.go_offline()


これで、Jupyterノートブック内でインタラクティブなPlotlyグラフを描くために必要なものが揃いました。

基本的なプロットのためのPlotly

このセクションでは、Plotly ライブラリを使用して基本的なインタラクティブなプロットを描画します。

次のセクションでは、地理的なデータをプロットするために Plotly をどのように使うかを見ていきます。

データセット

この節で使うデータセットは、Seabornライブラリと一緒にデフォルトでダウンロードされる “Tips” データセットである。

このデータセットには、あるグループの人々がランチやディナーで使った金額に関する情報が含まれている。

このデータセットには、性別、価格、チップ、年齢、サイズ、曜日、時間、昼食や夕食をとった人が喫煙者かどうか、が含まれている。

次のスクリプトは、データセットをインポートして、データセットの最初の5行を表示する。

import seaborn as sns


dataset = sns.load_dataset('tips')


dataset.head()


スクリプトの出力は次のようなものである。

出力から、このデータセットには3つの数値カラムがあることがわかる。

出力から、このデータセットには total_billtipsize の3つの数値カラムと、4つのカテゴリカラムがあることがわかる。

sexsmokerdaytime` の4つのカテゴリーカラムがあります。

Plotly を使ってインタラクティブなプロットを描く前に、静的なグラフを描くために Pandas をどのように使っていたかを思い出してみましょう。

データフレームに対して plot() メソッドを呼び出して、Pandasがどのように静的なプロットを行うかを見てみましょう。

ここでは、’total_bill’, ‘tip’, ‘sex’のカラムの値をプロットします。

以下のスクリプトを見てください。

dataset2 = dataset[["total_bill", "tip", "size"]]
dataset2.plot()


グラフをプロットするために、単純にデータフレームに対して plot メソッドを呼び出していることがわかります。

出力は以下の通りです。

出力から、’total_bill’ と ‘tips’ カラムの静的折れ線グラフを見ることができます。

それでは、Plotlyを使ってどのようにインタラクティブなプロットを描けるか見てみましょう。

ライブラリをインポートするセクションで、 plotly.offline モジュールから plot() 関数をインポートしています。

Pandasのデータフレームを使用してインタラクティブにプロットするには、 plot メソッドの代わりに iplot() メソッドを呼び出すだけでよいのです。

以下の例を見てください。

dataset2.iplot()


上記のスクリプトを実行すると、以下のように total_bill, tip, sex のカラムに対してインタラクティブな折れ線グラフが表示されるはずです。

プロットの上にカーソルを置くと、値が変化しているのがわかると思います。

プロットの右上にあるオプションを使って、プロットをズームインしたりズームアウトしたりすることができます。

また、プロットから列を追加したり削除したりすることができます。

最後に、グラフを静止画像として保存することもできます。

残りのセクションでは、Plotlyを使って最もよく使われるインタラクティブなプロットのいくつかをプロットします。

バー・プロット

Plotly を使ってインタラクティブに棒グラフを描画するには、iplot() 関数を使用します。

plot()関数のkindパラメータの値として、"bar" を渡す必要があります。

さらに、グラフをプロットしたいカテゴリカルカラムのリストをx属性に渡す必要があります。

最後に、数値列はy属性に値として渡されます。

次のスクリプトは、x 軸にtimesexのカラム、y 軸にtotal_bill` のカラムを指定して棒グラフをプロットします。

dataset.iplot(kind='bar', x=['time', 'sex'],y='total_bill')


出力

出力から、総請求額に対して4本の棒グラフがプロットされていることがわかります。

棒グラフは sextime の列の値のすべての可能な組み合わせを表しています。

棒グラフの列を指定することに加えて、単純に Pandas データフレーム上で集約関数を呼び出し、次に iplot() 関数を呼び出して kind 属性の値として “bar” を渡すことができます。

これは、集約関数にしたがって、すべての数値列に対して棒グラフをプロットします。

例えば、total_bill, tip, size カラムの平均値を含む棒グラフをプロットしたい場合は、以下のスクリプトを使用します。

dataset.mean().iplot(kind='bar')


出力

出力では、total_bill, tipsize カラムの平均値を含む棒グラフを見ることができます。

縦棒グラフの他に、横棒グラフも作成することができます。

以下のスクリプトのように、kind パラメータに属性として “barh” を渡すだけでよい。

dataset.mean().iplot(kind='barh')


出力

出力では、total_bill, tip, size カラムの平均値の水平棒グラフを見ることができます。

散布図

インタラクティブな散布図を作成するには、 iplot() 関数の kind パラメータの値として “scatter” を渡す必要があります。

さらに、x 軸と y 軸の列名を渡す必要があります。

次のスクリプトは、x 軸に total_bill カラム、y 軸に tip カラムを指定して散布図を描画するものです。

dataset.iplot(kind='scatter', x='total_bill', y='tip', mode='markers')


出力

マウスをインタラクティブプロットの上に置くと、total_billtip のカラムの値の変化を見ることができます。

ボックスプロット

以前の記事で、箱ひげ図とは何か、そしてSeabornライブラリを使ってどのように描けるかを説明しました。

箱ひげ図は、数値列の四分位情報をプロットします。

下ひげと箱の底の間の距離は、第1四分位を表示します。

箱の底と箱の真ん中との距離は、第2四分位を表示します。

同様に、箱の中央から箱の上端までの距離は第3四分位を、箱の上端から上ひげまでの距離は最後の四分位を表示する。

Plotlyを使用すると、インタラクティブな箱ひげ図を描くことができます。

以下のように、 iplot() 関数の kind パラメータに box を渡すだけでよいのです。

dataset2.iplot(kind='box')


出力では、データ中のすべての数値列、すなわち total_bill, tip, size に対する箱ひげ図が表示されます。

出力

歴史プロット

Plotly ライブラリは、データセットの任意の列に対してインタラクティブなヒストグラムプロットを作成することもできます。

dataset['total_bill'].iplot(kind='hist',bins=25)


出力

出力:

散布図プロット

散布図行列プロットは、基本的にデータセット中の数値列のすべての散布図のセットです。

dataset2.scatter_matrix()


スプレッド・プロット

スプレッドプロットは、任意の特定の点における2つ以上の数値列の間のスプレッドを表示します。

例えば、total_biltipの間の広がりを見るには、以下のようにspread関数を使用します。

dataset[['total_bill','tip']].iplot(kind='spread')


出力

出力から、total_billが増加するにつれて、total_billtipの間のスプレッドも増加することがわかります。

3Dプロット

最後に、2Dプロットに加えて、Plotlyライブラリを用いて3Dのインタラクティブなプロットを作成することができます。

例えば、total_bill, tip, size のカラムの3Dプロットを見るには、以下のスクリプトを実行します。

dataset2 = dataset[["total_bill", "tip", "size"]]
data = dataset2.iplot(kind='surface', colorscale='rdylbu')


出力では、3Dプロットを見ることができ、プロットを動かしたり、回転させたり、ズームイン・ズームアウトしたりすることができます。

出力

このセクションでは、Plotlyで最もよく使われるインタラクティブなプロットのいくつかを見てきました。

次の章では、Plotly ライブラリを使って地理的なデータをプロットする方法を見ていきます。

地理的プロットのためのPlotly

Plotlyで地理的なプロットを描くには、Choropleth Mapsを使用することにします。

Choropleth Maps は Plotly の特殊なプロットで、地理的なデータをプロットするために使用されます。

人民図の使い方に関する詳しいドキュメントはこちらにあります。

このセクションでは、アメリカ合衆国と全世界の地理的な地図を描く方法を、例を使って説明します。

しかし、実際に地理的プロットを描くコードを書く前に、まず必要なライブラリをインポートしましょう。

import plotly.plotly as py
import plotly.graph_objs as go
from plotly.offline import download_plotlyjs, init_notebook_mode, plot, iplot


init_notebook_mode(connected=True)
import pandas as pd


アメリカ合衆国の地理的地図

Plotlyを使って地形図を描くには、4つのステップがあります。

ステップ1:データディクショナリーを作成する

最初のステップは、実際に地図上に表示したいデータを含むデータディクショナリーを作成することです。

これを行うには、以下のスクリプトを実行します。

この後、1行ずつ説明します。

map_data = dict(type='choropleth',
            locations=['MI', 'CO', 'FL', 'IN'],
            locationmode='USA-states',
            colorscale='Portland',
            text=['Michigan', 'Colorado', 'Florida', 'Indiana'],
            z=[1.0,2.0,3.0,4.0],
            colorbar=dict(title="USA States")
           )


データ辞書のいくつかのキーに値を指定する必要があります。

それらは次のとおりです。

    1. type: ここでは、人口地図を使用しているので、タイプは常に choropleth になります。
    1. locations: ここでは、地図上に表示したい州の略称を渡します。地図には4つの州が表示されます。ミシガン州(MI)’、’コロラド州(CO)’、’フロリダ州(FL)’、’インディアナ州(IN)’
    1. locationmodeUSA-state にします。これは、アメリカ合衆国のみ地図を表示するためです。
    1. colorscale: このキーはプロットの色を指定するために使用されます。その他の色のオプションについては、ドキュメントを参照してください。
    1. text: マウスを状態の場所に合わせたときに表示される文字列のリストです。
    1. z キーには、マウスを状態の位置に合わせたときに表示される数値のリストが含まれています。
    1. colorbar は辞書です。タイトル`キーには、カラーバーに表示されるテキストを指定します。
ステップ2: レイアウトの作成

データ辞書を作成したら、次のステップではレイアウト辞書を作成します。

USAのレイアウト辞書は、以下のスクリプトのようにシンプルなものです。

map_layout = dict(geo = {'scope':'usa'})


この辞書は geo という名前の別の辞書を受け取ります。

マップはUSAに限定されているので、scopeのキーに “usa “という値を渡しました。

ステップ3: グラフオブジェクトの作成

ライブラリをインポートするところで、plotly.graph_objsというクラスをインポートしました。

3番目のステップは、このグラフのオブジェクトを作成することです。

これを行うには、オブジェクトから Figure 関数を呼び出す必要があります。

オブジェクトは2つのパラメータを持ちます。

datalayout` です。

以下のように、最初のパラメータにデータ辞書を、2番目のパラメータにレイアウト辞書を渡すことにします。

map_actual = go.Figure(data=[map_data], layout=map_layout)


ステップ4: iplot() メソッドの呼び出し

最後に、以下のように iplot() 関数を呼び出して、3番目のステップで作成したグラフオブジェクトを渡します。

iplot(map_actual)


出力では、米国の4つの州の地理的なプロットを見ることができます。

残りの州は、それらの州に関する情報を何も指定しなかったので、色付けされていないことがわかります。

色付けされた州にマウスを乗せると、データ辞書を作成したときに指定した textz キーの対応する値が表示されます。

CSVによる米国の地形図

さて、Plotlyを使った地理プロットの作成方法と、コレポリスマップの基本的な考え方はわかりました。

では、もっと複雑な地図を作成してみましょう。

CSVファイルのデータを使ってどのように地理的プロットを作成するかを見ていきます。

ここでは、米国の全州の一人当たりGDPを表示する地理的な地図を作成します。

データセット

このセクションのデータセットは、このKaggleリンクからダウンロードすることができ、CSV形式で提供されています。

読みやすくするためにファイル名を変更しました。

以下のスクリプトはデータセットをインポートし、その最初の5行をコンソールに表示します。

df = pd.read_csv(r'E:/state_gdp.csv')
df.head()


出力はこのようになる。

このデータセットには、Areaカラムにアメリカの州の名前が含まれている。

このデータセットには、2013年から2017年までの5年間の一人当たりのGDPも含まれています。

我々は、2017年のデータをプロットします。

このデータセットの問題点は、州のフルネームが含まれているのに対して、チョロプス・マップは州の名前の略称を受け入れることです。

最初にしなければならないのは、州名の略称を含む列をデータセットに追加することです。

これを行う方法の 1 つは、州名とその省略形の辞書を作成し、後でその辞書から省略形の値を含む列を作成することです。

次のスクリプトは、キーが完全な州名、値が対応する州略称であるディクショナリを作成します。

us_state_abbrev = {
    'Alabama': 'AL',
    'Alaska': 'AK',
    'Arizona': 'AZ',
    'Arkansas': 'AR',
    'California': 'CA',
    'Colorado': 'CO',
    'Connecticut': 'CT',
    'Delaware': 'DE',
    'Florida': 'FL',
    'Georgia': 'GA',
    'Hawaii': 'HI',
    'Idaho': 'ID',
    'Illinois': 'IL',
    'Indiana': 'IN',
    'Iowa': 'IA',
    'Kansas': 'KS',
    'Kentucky': 'KY',
    'Louisiana': 'LA',
    'Maine': 'ME',
    'Maryland': 'MD',
    'Massachusetts': 'MA',
    'Michigan': 'MI',
    'Minnesota': 'MN',
    'Mississippi': 'MS',
    'Missouri': 'MO',
    'Montana': 'MT',
    'Nebraska': 'NE',
    'Nevada': 'NV',
    'New Hampshire': 'NH',
    'New Jersey': 'NJ',
    'New Mexico': 'NM',
    'New York': 'NY',
    'North Carolina': 'NC',
    'North Dakota': 'ND',
    'Ohio': 'OH',
    'Oklahoma': 'OK',
    'Oregon': 'OR',
    'Pennsylvania': 'PA',
    'Rhode Island': 'RI',
    'South Carolina': 'SC',
    'South Dakota': 'SD',
    'Tennessee': 'TN',
    'Texas': 'TX',
    'Utah': 'UT',
    'Vermont': 'VT',
    'Virginia': 'VA',
    'Washington': 'WA',
    'West Virginia': 'WV',
    'Wisconsin': 'WI',
    'Wyoming': 'WY',
}


次のステップは、データセットに略語を含むカラムを追加することです。

これは、Area カラムの値を us_state_abbrev ディクショナリのキーに対応させることで実現できます。

そして、以下のように、新しく作成した略語のカラムに対応する値を追加することができます。

df['abbrev'] = df['Area'].map(us_state_abbrev)


ここで、もう一度 head() 関数を使用してデータフレームの先頭を表示すると、以下のように新しく作成された abbrev カラムが表示されます。

df.head()


出力はこのようになります。

abbrevカラムには、州の略称が表示されていることがわかります。

ここで重要なのは、Areaカラムは国全体の値も持っているということです。

しかし、この国はabbrev` 列に対応する省略形が NaN となるため、グラフをプロットする際には無視されることになります。

さて、データの前処理が終わったので、次のステップは簡単である。

まず、以下のようにデータセットからの値を含むデータ辞書を作成する。

map_data = dict(type='choropleth',
            locations=df['abbrev'],
            locationmode='USA-states',
            colorscale='Reds',
            text=df['Area'],
            marker=dict(line=dict(color='rgb(255,0,0)', width=2)),
            z=df['2017'],
            colorbar=dict(title="GDP Per Capita - 2017")
           )


上のスクリプトでは、locationsのキーにデータセットのabbrevカラムを渡しているのがわかると思います。

これは、アメリカの全州の地理的なプロットが画面に表示されることを意味します。

同様に、text キーには、州のフルネームを含む “Area” カラムを渡しています。

最後に、「z`」キーには、2017年の一人当たりGDPを渡します。

また、ここでは新しいキー、すなわち marker を使用していることも重要です。

これは、異なる州間の境界線を作成するために使用されます。

RGB値「255,0,0」は、境界線が赤であることを意味します。

幅が2であれば、ボーダーの幅は2ピクセルになります。

次のステップは、地図のレイアウトを作成することです。

次のスクリプトはそれを行うものです。

map_layout = dict(title='USA States GDP Per Capita - 2017',
              geo=dict(scope='usa',
                         showlakes=True,
                         lakecolor='rgb(85,173,240)')
             )


上のスクリプトでは showlakes のキーに True を渡しています。

これは、湖が地図上に表示され、その色が rgb(85,173,240) の RGB 値で指定された水色になることを意味します。

最後に、グラフオブジェクトを作成し、データとレイアウトディクショナリを渡す必要があります。

次のスクリプトを見てください。

map_actual = go.Figure(data=[map_data], layout=map_layout)


最後のステップとして、iplot() メソッドを呼び出し、新しく作成したグラフオブジェクトを渡す必要があります。

iplot(map_actual)


上記のスクリプトを実行すると、アメリカ合衆国の地図と一人当たりのGDPが表示されます。

色の薄い州は色の濃い州よりGDPが小さい。

世界の地理地図

前のセクションでは、アメリカ合衆国のグラフィカルな地図を見てきました。

このセクションでは、世界の地理的なマップをプロットする方法を説明します。

手順はほぼ同じです。

まず、データ辞書を作成し、次にレイアウト辞書とグラフオブジェクトを作成します。

最後に、iplot()関数を使ってグラフを描画します。

データセット

今回使用するデータセットは、1960年から2016年までの世界の国別人口を含んでいます。

我々は、2016年の各国の人口を表示する世界の地理的な地図をプロットする予定です。

データセットは、このKaggleのリンクからダウンロードすることができます。

データセットはCSV形式でダウンロードされます。

次のスクリプトはデータセットをインポートし、head()メソッドを使って最初の5行を表示します。

df = pd.read_csv(r'E:/world_pop.csv')
df.head()


次の画像は出力のスクリーンショットです。

先ほど読み込んだ母集団のデータセットから、プロットしたいデータの情報を格納するデータ辞書を作成してみましょう。

map_data = dict(
        type='choropleth',
        locations=df['Country Code'],
        z=df['2016'],
        text=df['Country'],
        colorbar={'title': 'World Population 2016'},
      )


上のスクリプトから、唯一の変更は locations キーであることがわかるでしょう。

ここでは、州の略称の代わりに “Country Code” を渡しています。

これは、世界の地理的なプロットを作成するための必須条件です。

textキーには、国の正式名称を含む "Country" カラムの値を渡します。

同様に、z`キーには、”2016 “列の値を渡します。

これは、2016年の人口値を含む列であるためです。

次のステップは、レイアウト辞書の作成です。

次のスクリプトを見てください。

map_layout = dict(
    title='World Population 2016',
    geo=dict(showframe=False)
)


レイアウトでは、geo辞書の showFrame キーを変更するだけです。

このキーが False に設定されている場合、結果のプロットは境界を持ちません。

次に、Plotlyグラフオブジェクトを作成し、下図のように作成したデータとレイアウト辞書の両方を渡す必要があります。

map_actual = go.Figure(data=[map_data], layout=map_layout)


最後のステップとして、 iplot() 関数を呼び出して、先ほど作成したグラフオブジェクトを渡す必要があります。

出力はこのようになるはずです。

出力では、全世界の地図と人口密度を見ることができます。

インドと中国の地図は、他の国々と比べて暗いことがわかります。

なぜなら、これらの国は、人口の少ないヨーロッパの国々と比べて、はるかに人口が多いからです。

どの国にもマウスカーソルを合わせると、その国の名前と総人口が表示されます。

Plotlyやその他のPythonの可視化ライブラリについて、より詳細なガイドをお探しですか?最も人気のある9つのライブラリについて、そのユニークな機能、強み、ニュアンスを含む素晴らしいリソースがある、Data Visualization in Pythonをチェックしてください。

結論

Plotly はインタラクティブなデータ可視化のための非常に便利な Python ライブラリです。

この記事では、散布図、折れ線グラフ、ヒストグラム、基本的な3Dプロットのような基本的なグラフを描くためにPlotlyをどのように使用できるかを見ました。

また、Plotly を使って、コレポリスマップを使った地理的なプロットを描く方法も見てきました。

例として、アメリカ合衆国の地理的プロットと全世界の地理的プロットを作図しました。

このように、choropleth ライブラリにはたくさんの機能がありますので、皆さんもぜひ、地理的なプロットを作成する練習をしてみてください。

コレプシスマップの詳細なドキュメントはこちらのリンクから入手できます:https://plot.ly/python/choropleth-maps/。

タイトルとURLをコピーしました