カテゴリー

Pythonでの比較

【plotly&pandas】df.plot()でPlotlyのグラフを作成

2021年11月8日

こんな人にオススメ

pnadasのデータフレームからすぐにプロットするdf.plot()plotlyのグラフは作成できるの?

ということで、今回はpandasdf.plot()を使いデータフレームからすぐにplotlyのグラフ作成の方法について解説する。シンプルにdf.plot()するとmatplotlibplt)でグラフができるが、実は一工夫でplotly版のグラフも作成可能。

いちいち色んなコードを作成しなくてもサクッとグラフが作成できるのでデータ確認に最適だ。

本記事で解説したグラフ以外の種類のグラフの作成も可能。詳しくはandasの「pandas.DataFrame.plot」やPlotlyの「Pandas Plotting Backend in Python」を参照。

なお、df.plot()pltのグラフを作成したい場合は以下の記事で開設しているので参照いただきたい。

【plt&pandas】df.plot()でmatplotlibのグラフを作成

続きを見る

python環境は以下。

  • Python 3.10.1
  • pandas 1.3.5
  • matplotlib 3.5.1
  • plotly 5.4.0
  • plotly-orca 3.4.2

運営者のメガネです。YouTubeTwitterInstagramも運営中。自己紹介お問い合わせページあります。

運営者メガネ

作成したコード全文

初期のdf.plot()plt

import pandas as pd

# 初期状態
print(pd.options.plotting.backend)
# matplotlib

# ['Altair', 'pandas_bokeh', 'Seaborn', 'plotnine', 'IPython vega', 'Plotly', 'Lux', 'Qtpandas', 'D-Tale', 'hvplot', ]

df.plot()で作成したグラフがどのライブラリのグラフの系列なのかを確認するにはpd.options.plotting.backendを出力する。

初期状態ではmatplotlilb、すなわちpltが設定されている。その他にも色んなライブラリを選択可能だが、今回はその中のplotlyに絞る。ただし、大文字で指定するとエラーになるから注意が必要。

シンプルにすると折れ線グラフ


まずはシンプルにdf.plot()してみる。この場合は折れ線グラフが描画される。基本デフォルトのグラフだが、フォントサイズは変更している。

グラフのサイズはpltではデフォルトの640 x 480ピクセル(4:3)、plotlyではデフォルトの450 x 700(9:14)ピクセルだ。

以下でグラフ作成の方法を解説するが、まずはこれらのグラフを作成するためのコードを示しておく。

import pandas as pd
import plotly.express as px
import plotly.io as pio

# シンプルにグラフ化

# 株価のデータ
df = px.data.stocks()

# 横軸が日付になるようにインデックスを設定
# データの型が異なるのでplotlyのプロット時にエラー
# ValueError: Plotly Express cannot process wide-form data with columns of different type.
df = df.set_index('date')
# df.set_index('date', inplace=True)  # これでも可能
print(df)
#                 GOOG      AAPL      AMZN        FB      NFLX      MSFT
# date
# 2018-01-01  1.000000  1.000000  1.000000  1.000000  1.000000  1.000000
# 2018-01-08  1.018172  1.011943  1.061881  0.959968  1.053526  1.015988
# 2018-01-15  1.032008  1.019771  1.053240  0.970243  1.049860  1.020524
# 2018-01-22  1.066783  0.980057  1.140676  1.016858  1.307681  1.066561
# 2018-01-29  1.008773  0.917143  1.163374  1.018357  1.273537  1.040708
# ...              ...       ...       ...       ...       ...       ...
# 2019-12-02  1.216280  1.546914  1.425061  1.075997  1.463641  1.720717
# 2019-12-09  1.222821  1.572286  1.432660  1.038855  1.421496  1.752239
# 2019-12-16  1.224418  1.596800  1.453455  1.104094  1.604362  1.784896
# 2019-12-23  1.226504  1.656000  1.521226  1.113728  1.567170  1.802472
# 2019-12-30  1.213014  1.678000  1.503360  1.098475  1.540883  1.788185

# [105 rows x 6 columns]

print(' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -')
# グラフ化

# pandasで作成するプロットの種類をplotlyに変更
pd.options.plotting.backend = 'plotly'
fig = df.plot()

# グラフ全体とホバーのフォントサイズ変更
fig.update_layout(font_size=20, hoverlabel_font_size=20)
fig.show()

# グラフ保存
prefix = 'dfplot-plotly'  # 保存ファイル名の接頭辞
save_name = f"{prefix}_simple"
pio.orca.config.executable = '/Applications/orca.app/Contents/MacOS/orca'
pio.write_html(fig, f"{save_name}.html")
pio.write_image(fig, f"{save_name}.png")

使用するデータ

# 株価のデータ
df = px.data.stocks()

# 横軸が日付になるようにインデックスを設定
# データの型が異なるのでplotlyのプロット時にエラー
# ValueError: Plotly Express cannot process wide-form data with columns of different type.
df = df.set_index('date')
print(df)
#                 GOOG      AAPL      AMZN        FB      NFLX      MSFT
# date
# 2018-01-01  1.000000  1.000000  1.000000  1.000000  1.000000  1.000000
# 2018-01-08  1.018172  1.011943  1.061881  0.959968  1.053526  1.015988
# 2018-01-15  1.032008  1.019771  1.053240  0.970243  1.049860  1.020524
# 2018-01-22  1.066783  0.980057  1.140676  1.016858  1.307681  1.066561
# 2018-01-29  1.008773  0.917143  1.163374  1.018357  1.273537  1.040708
# ...              ...       ...       ...       ...       ...       ...
# 2019-12-02  1.216280  1.546914  1.425061  1.075997  1.463641  1.720717
# 2019-12-09  1.222821  1.572286  1.432660  1.038855  1.421496  1.752239
# 2019-12-16  1.224418  1.596800  1.453455  1.104094  1.604362  1.784896
# 2019-12-23  1.226504  1.656000  1.521226  1.113728  1.567170  1.802472
# 2019-12-30  1.213014  1.678000  1.503360  1.098475  1.540883  1.788185

# [105 rows x 6 columns]

まず使用するデータだけど、これはplotlypxのものを使用。期間初めを1としたアメリカの主要企業の株価データ。

このデータフレームは0列目がdate列で1列目以降が各企業の株価だけど、そのままだとエラーでグラフ化できない。時刻データと数値データが混在しているから。

なので、df = df.set_index('date')date列をインデックスに移動している。なお、df.set_index('date')だけだと元のdfに反映されないのでdf = で反映させている。df.set_index('date', inplace=True)としてもいい。

plotlyのグラフを作成

# pandasで作成するプロットの種類をplotlyに変更
pd.options.plotting.backend = 'plotly'
fig = df.plot()

# グラフ全体とホバーのフォントサイズ変更
fig.update_layout(font_size=20, hoverlabel_font_size=20)
fig.show()

# グラフ保存
prefix = 'dfplot-plotly'  # 保存ファイル名の接頭辞
save_name = f"{prefix}_simple"
pio.orca.config.executable = '/Applications/orca.app/Contents/MacOS/orca'
pio.write_html(fig, f"{save_name}.html")
pio.write_image(fig, f"{save_name}.png")

ploltyの場合はpd.options.plotting.backend = ‘plotly’でバックエンドをplotlyに変更する必要がある。これを忘れるとmatplotlibになってしまう。

グラフ化は単にdf.plot()でするけど、グラフの表示などを行う際にはfig = df.plot()として変数に格納しておくと便利。

今回だとグラフのフォントサイズを変更しているが、変数figに入れておくことでfig.update_layoutとして簡単に変更可能。fig.update_layoutなどについては以下の記事参照。

【plotly&fig作成と更新】add_traceやupdate_layoutの使い方

続きを見る

 

fig.show()でグラフ化ができたらあとはグラフを保存するだけ。グラフの保存方法はいくつかあるが、執筆者はorcaを使用している。orcaについては以下。

plotlyでグラフを静止画として保存する際に出るポップアップ
【plotly&orca】plotlyで静止画保存(orca)

続きを見る

執筆者はいつもhtmlとpng形式でグラフを保存しているから、ここでもこれら2つの拡張子を使用。

凡例や軸ラベルを自動でつけてくれる

実はdf.plot()でグラフを作成すると自動で凡例や軸ラベルをつけてくれる。後述するように内容を変更することも可能だが、いちいち凡例の設置や軸ラベルの追加などを行う必要がない。

それぞれ指定してしまうと、管理するのも面倒だし変更するのも面倒。自動で追加してくれるのは楽チンでありがたい。

ただし、縦軸ラベルと凡例タイトルは自動でvaluevariableになる。これが嫌ならfig.update_layoutなどで別途変更する必要がある。

グラフのサイズやタイトル・軸ラベルを追加


今度はpltplotlyそれぞれのグラフのレイアウトを変更してみた。変更した内容は以下。

  • グラフタイトル
  • グラフのテンプレート
  • 横軸・縦軸ラベル
  • 凡例タイトル
  • 縦軸の接尾辞

縦軸の接尾辞は必要ないけど、こういうやり方もあるってことで紹介しておく。まずは上のグラフを作成するための全体コード。

以下でグラフ作成を解説するが、使用するデータやファイル保存名の指定方法は同じなので割愛する。

import pandas as pd
import plotly.express as px
import plotly.io as pio

# グラフレイアウトを変更

# 株価のデータ
df = px.data.stocks()

# 横軸が日付になるようにインデックスを設定
# データの型が異なるのでplotlyのプロット時にエラー
# ValueError: Plotly Express cannot process wide-form data with columns of different type.
df = df.set_index('date')
print(df)
#                 GOOG      AAPL      AMZN        FB      NFLX      MSFT
# date
# 2018-01-01  1.000000  1.000000  1.000000  1.000000  1.000000  1.000000
# 2018-01-08  1.018172  1.011943  1.061881  0.959968  1.053526  1.015988
# 2018-01-15  1.032008  1.019771  1.053240  0.970243  1.049860  1.020524
# 2018-01-22  1.066783  0.980057  1.140676  1.016858  1.307681  1.066561
# 2018-01-29  1.008773  0.917143  1.163374  1.018357  1.273537  1.040708
# ...              ...       ...       ...       ...       ...       ...
# 2019-12-02  1.216280  1.546914  1.425061  1.075997  1.463641  1.720717
# 2019-12-09  1.222821  1.572286  1.432660  1.038855  1.421496  1.752239
# 2019-12-16  1.224418  1.596800  1.453455  1.104094  1.604362  1.784896
# 2019-12-23  1.226504  1.656000  1.521226  1.113728  1.567170  1.802472
# 2019-12-30  1.213014  1.678000  1.503360  1.098475  1.540883  1.788185

# [105 rows x 6 columns]

print(' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -')
# グラフ化

# plotlyに変更
pd.options.plotting.backend = 'plotly'

# レイアウトの変更は引数で可能
fig = df.plot(
    # グラフタイトル
    title='px.data.stock()',
    # レイアウトのテンプレート
    template='simple_white',
    # 横軸、縦軸、凡例のラベル
    labels=dict(
        index='date',  # 横軸ラベル
        value='Relative stock price',  # 縦軸ラベル
        variable='Company'  # 凡例タイトル
    ),
)
fig.update_yaxes(ticksuffix='!')  # y軸に接尾辞をつける

# グラフ全体とホバーのフォントサイズ変更
fig.update_layout(font_size=20, hoverlabel_font_size=20)
# fig.show()

# グラフ保存
prefix = 'dfplot-plotly'  # 保存ファイル名の接頭辞
save_name = f"{prefix}_layout"
pio.orca.config.executable = '/Applications/orca.app/Contents/MacOS/orca'
pio.write_html(fig, f"{save_name}.html")
pio.write_image(fig, f"{save_name}.png")

軸ラベル・凡例タイトルの指定には注意が必要

# plotlyに変更
pd.options.plotting.backend = 'plotly'

# レイアウトの変更は引数で可能
fig = df.plot(
    # グラフタイトル
    title='px.data.stock()',
    # レイアウトのテンプレート
    template='simple_white',
    # 横軸、縦軸、凡例のラベル
    labels=dict(
        index='date',  # 横軸ラベル
        value='Relative stock price',  # 縦軸ラベル
        variable='Company'  # 凡例タイトル
    ),
)
fig.update_yaxes(ticksuffix='!')  # y軸に接尾辞をつける

# グラフ全体とホバーのフォントサイズ変更
fig.update_layout(font_size=20, hoverlabel_font_size=20)
fig.show()

# グラフ保存
prefix = 'dfplot-plotly'  # 保存ファイル名の接頭辞
save_name = f"{prefix}_layout"
pio.orca.config.executable = '/Applications/orca.app/Contents/MacOS/orca'
pio.write_html(fig, f"{save_name}.html")
pio.write_image(fig, f"{save_name}.png")

グラフタイトルや軸ラベルを追加・変更したけど、これらはdf.plot()の中ので引数で設定可能。例えばグラフタイトルはtitleで可能。

しかし、軸ラベルと凡例タイトルは引数labelの中で行う必要がある。さらに横軸ラベルはindex、縦軸ラベルはvalue、凡例タイトルはvariable

通常は横軸ならxlabelxaxes_titleなどで設定するが、ここが異なるので注意が必要。横軸ラベルをfig.update_layoutで変更する場合は以下のようにする。

fig.update_layout(xaxes_title='date')

また、縦軸ラベルに接尾辞をつけたが、これはdf.plot()では対応できないようだ。なので、これはfig.update_layoutの縦軸版のfig.update_yaxesで対応。

接尾辞はsuffixで、軸の目盛に反映させることからticksuffix=’!’の形式で書く必要がある。

プロットの線の種類を変更


続いてはプロットの線の種類を変更する。普通にグラフ化するだけだと全てのグラフが実線になる。これだと分かりにくい時に使える方法だ。

全体コードは以下。使用するデータはこれまでと同じ。

import pandas as pd
import plotly.express as px
import plotly.io as pio

# プロットの線の種類を変更

# 株価のデータ
df = px.data.stocks()

# 横軸が日付になるようにインデックスを設定
# データの型が異なるのでplotlyのプロット時にエラー
# ValueError: Plotly Express cannot process wide-form data with columns of different type.
df = df.set_index('date')
print(df)
#                 GOOG      AAPL      AMZN        FB      NFLX      MSFT
# date
# 2018-01-01  1.000000  1.000000  1.000000  1.000000  1.000000  1.000000
# 2018-01-08  1.018172  1.011943  1.061881  0.959968  1.053526  1.015988
# 2018-01-15  1.032008  1.019771  1.053240  0.970243  1.049860  1.020524
# 2018-01-22  1.066783  0.980057  1.140676  1.016858  1.307681  1.066561
# 2018-01-29  1.008773  0.917143  1.163374  1.018357  1.273537  1.040708
# ...              ...       ...       ...       ...       ...       ...
# 2019-12-02  1.216280  1.546914  1.425061  1.075997  1.463641  1.720717
# 2019-12-09  1.222821  1.572286  1.432660  1.038855  1.421496  1.752239
# 2019-12-16  1.224418  1.596800  1.453455  1.104094  1.604362  1.784896
# 2019-12-23  1.226504  1.656000  1.521226  1.113728  1.567170  1.802472
# 2019-12-30  1.213014  1.678000  1.503360  1.098475  1.540883  1.788185

# [105 rows x 6 columns]

print(' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -')
# グラフ化

# pandasで作成するプロットの種類をplotlyに変更
pd.options.plotting.backend = 'plotly'
fig = df.plot()

# 線の種類を変更
fig.data[1].line.dash = 'dash'
fig['data'][2]['line']['dash'] = 'dot'
fig['data'][3]['line_dash'] = 'dashdot'

# グラフ全体とホバーのフォントサイズ変更
fig.update_layout(font_size=20, hoverlabel_font_size=20)
fig.show()

# グラフ保存
prefix = 'dfplot-plotly'  # 保存ファイル名の接頭辞
save_name = f"{prefix}_linestyle"
pio.orca.config.executable = '/Applications/orca.app/Contents/MacOS/orca'
pio.write_html(fig, f"{save_name}.html")
pio.write_image(fig, f"{save_name}.png")

線の種類の変更にはいろんな種類がある。ここでは3つの方法で線の種類を変更してみた。それぞれApple、Amazon、Facebook(現Meta)を変更。

figの中身はdictのような構造となっているので、.を使ってアクセスしてもいいし、[’data’]のように要素を指定してアクセスしてもいい。

さらにPlotlyでは['line']['dash']のように連続した要素指定は、_を使って['line_dash']のように書くことができる。この時の_をマジックアンダースコアという。

# 線の種類を変更
fig.data[1].line.dash = 'dash'  # AAPL
fig['data'][2]['line']['dash'] = 'dot'  # AMZN
fig['data'][3]['line_dash'] = 'dashdot'  # FB

これらの方法で線の種類を変更するコードを書いたグラフ化コードが以下。

なお、今回はAAPL、AMZN、FBだけ線の種類を変更したので、それ以外のNFLX、GOOG、MSFTは実線のまま。

# plotly

# pandasで作成するプロットの種類をplotlyに変更
pd.options.plotting.backend = 'plotly'
fig = df.plot()

# 線の種類を変更
fig.data[1].line.dash = 'dash'  # AAPL
fig['data'][2]['line']['dash'] = 'dot'  # AMZN
fig['data'][3]['line_dash'] = 'dashdot'  # FB

# グラフ全体とホバーのフォントサイズ変更
fig.update_layout(font_size=20, hoverlabel_font_size=20)
fig.show()

# グラフ保存
prefix = 'dfplot-plotly'  # 保存ファイル名の接頭辞
save_name = f"{prefix}_linestyle"
pio.orca.config.executable = '/Applications/orca.app/Contents/MacOS/orca'
pio.write_html(fig, f"{save_name}.html")
pio.write_image(fig, f"{save_name}.png")

プロットの色を変更


プロットの色を変更するには1プロットずつ指定する必要がある。一括でできないようだ。

import pandas as pd
import plotly.express as px
import plotly.io as pio

# 1プロットずつ色を変更

# 株価のデータ
# dateをインデックスに移動するのを1行で済ませた
df = px.data.stocks().set_index('date')

print(' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -')
# グラフ化

# pandasで作成するプロットの種類をplotlyに変更
pd.options.plotting.backend = 'plotly'
fig = df.plot()

# 各ブランドの色
colors = {
    'GOOG': '#34a853', 'AAPL': '#000000', 'AMZN': '#ff9900',
    'FB': '#1877f2', 'NFLX': '#e50914', 'MSFT': '#f65314'
}

# 各プロットずつ色を変更
for num, datum in enumerate(fig.data):
    fig.data[num]['line']['color'] = colors[datum['name']]

# グラフ全体とホバーのフォントサイズ変更
fig.update_layout(font_size=20, hoverlabel_font_size=20)
fig.show()

# グラフ保存
prefix = 'dfplot-plotly'  # 保存ファイル名の接頭辞
save_name = f"{prefix}_color"
pio.orca.config.executable = '/Applications/orca.app/Contents/MacOS/orca'
pio.write_html(fig, f"{save_name}.html")
pio.write_image(fig, f"{save_name}.png")

プロットの色は各企業のブランドカラーをdictで作成。GoogleやMicrosoftは複数色あるけど、他のプロットと被らないような色にしておいた。

これらの色を作成したfigdataの中の各企業のプロットカラーに反映させる。fig.dataの中身は以下。

各企業のプロットデータがtuple形式で入っており、その中にxyなどがdict形式で格納されている。

fig.dataにアクセスできたら、あとは各企業について[’line’][’color’]というようにプロット線の色を変更すれば良い。

一括で変更できないから、ここではforループで各企業を回すことにする。

# 各ブランドの色
colors = {
    'GOOG': '#34a853', 'AAPL': '#000000', 'AMZN': '#ff9900',
    'FB': '#1877f2', 'NFLX': '#e50914', 'MSFT': '#f65314'
}

# 各プロットずつ色を変更
for num, datum in enumerate(fig.data):
    fig.data[num]['line']['color'] = colors[datum['name']]

あとはグラフ化するのみ。グラフ化部分のコードは以下。

# グラフ化

# pandasで作成するプロットの種類をplotlyに変更
pd.options.plotting.backend = 'plotly'
fig = df.plot()

# 各ブランドの色
colors = {
    'GOOG': '#34a853', 'AAPL': '#000000', 'AMZN': '#ff9900',
    'FB': '#1877f2', 'NFLX': '#e50914', 'MSFT': '#f65314'
}

# 各プロットずつ色を変更
for num, datum in enumerate(fig.data):
    fig.data[num]['line']['color'] = colors[datum['name']]

# グラフ全体とホバーのフォントサイズ変更
fig.update_layout(font_size=20, hoverlabel_font_size=20)
fig.show()

# グラフ保存
prefix = 'dfplot-plotly'  # 保存ファイル名の接頭辞
save_name = f"{prefix}_color"
pio.orca.config.executable = '/Applications/orca.app/Contents/MacOS/orca'
pio.write_html(fig, f"{save_name}.html")
pio.write_image(fig, f"{save_name}.png")

df.plot.scatter()で散布図を作成


散布図を作成するにはdf.plot.scatterとするだけ。ただし、scatterの場合はxyの両方を指定する必要があるので注意。

今回はdate列を横軸に、各企業の株価データを縦軸にする。先ほどまでと同じ。

Plotlyでの散布図の作成方法は以下の記事で詳しく解説している。

【plotly&go.Scatter】plotlyの散布図グラフの描き方

続きを見る

【plotly&px.scatter】pxでの散布図の描き方

続きを見る

import pandas as pd
import plotly.express as px
import plotly.io as pio

# 散布図を作成

# 株価のデータ
df = px.data.stocks().set_index('date')
print(df)
#                 GOOG      AAPL      AMZN        FB      NFLX      MSFT
# date
# 2018-01-01  1.000000  1.000000  1.000000  1.000000  1.000000  1.000000
# 2018-01-08  1.018172  1.011943  1.061881  0.959968  1.053526  1.015988
# 2018-01-15  1.032008  1.019771  1.053240  0.970243  1.049860  1.020524
# 2018-01-22  1.066783  0.980057  1.140676  1.016858  1.307681  1.066561
# 2018-01-29  1.008773  0.917143  1.163374  1.018357  1.273537  1.040708
# ...              ...       ...       ...       ...       ...       ...
# 2019-12-02  1.216280  1.546914  1.425061  1.075997  1.463641  1.720717
# 2019-12-09  1.222821  1.572286  1.432660  1.038855  1.421496  1.752239
# 2019-12-16  1.224418  1.596800  1.453455  1.104094  1.604362  1.784896
# 2019-12-23  1.226504  1.656000  1.521226  1.113728  1.567170  1.802472
# 2019-12-30  1.213014  1.678000  1.503360  1.098475  1.540883  1.788185

# [105 rows x 6 columns]

print(' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -')
# グラフ化

# pandasで作成するプロットの種類をplotlyに変更
pd.options.plotting.backend = 'plotly'

# plotlyは一括でグラフ化可能
fig = df.plot.scatter(x=df.index, y=df.columns[1:].values)

# グラフ全体とホバーのフォントサイズ変更
fig.update_layout(font_size=20, hoverlabel_font_size=20)
fig.show()

# グラフ保存
prefix = 'dfplot-plotly'  # 保存ファイル名の接頭辞
save_name = f"{prefix}_scatter"
pio.orca.config.executable = '/Applications/orca.app/Contents/MacOS/orca'
pio.write_html(fig, f"{save_name}.html")
pio.write_image(fig, f"{save_name}.png")

横軸はデータフレームのインデックスとして指定したdateを使用するので、df.indexとする。一方で、縦軸はdf.columns[1:].valuesとすることで各企業を一括でグラフ化することが可能。

# plotlyは一括でグラフ化可能
fig = df.plot.scatter(x=df.index, y=df.columns[1:].values)

1企業ずつforを使ってプロットしてもいいけど、その場合は既存のfigfig.add_traceという形で追加しないといけない。これはこれで面倒。なので一括でプロット。

【plotly&fig作成と更新】add_traceやupdate_layoutの使い方

続きを見る

[card2 id=""]

あとはフォントサイズ変更とグラフの表示と保存。これまで通り。

# グラフ化

# pandasで作成するプロットの種類をplotlyに変更
pd.options.plotting.backend = 'plotly'

# plotlyは一括でグラフ化可能
fig = df.plot.scatter(x=df.index, y=df.columns[1:].values)

# グラフ全体とホバーのフォントサイズ変更
fig.update_layout(font_size=20, hoverlabel_font_size=20)
fig.show()

# グラフ保存
prefix = 'dfplot-plotly'  # 保存ファイル名の接頭辞
save_name = f"{prefix}_scatter"
pio.orca.config.executable = '/Applications/orca.app/Contents/MacOS/orca'
pio.write_html(fig, f"{save_name}.html")
pio.write_image(fig, f"{save_name}.png")

df.plot.bar()で棒グラフを作成


棒グラフを作成することも可能。df.plot.bar()とすることで簡単にグラフ化することができる。ただし、これまでの株価データだと棒グラフにしづらかったので、新たにデータを作成した。

Plotlyでの棒グラフの作成方法は以下の記事で詳しく解説している。

【plotly&棒グラフ】go.Barでバーチャートを作成

続きを見る

【plolty&棒グラフ】px.barでバーチャートを作成

続きを見る

import pandas as pd
import plotly.express as px
import plotly.io as pio

# 棒グラフを作成

# 株価のデータ
df = pd.DataFrame(dict(a=[1, 3, 2], b=[3, 2, 1]))
print(df)
#    a  b
# 0  1  3
# 1  3  2
# 2  2  1

print(' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -')
# グラフ化

# pandasで作成するプロットの種類をplotlyに変更
pd.options.plotting.backend = 'plotly'
fig = df.plot.bar()

# 積み上げ式ではなく、横並びにする場合はbarmode='group'
fig.update_layout(barmode='group')
# グラフ全体とホバーのフォントサイズ変更
fig.update_layout(font_size=20, hoverlabel_font_size=20)
# fig.show()

# グラフ保存
prefix = 'dfplot-plotly'  # 保存ファイル名の接頭辞
save_name = f"{prefix}_bar"
pio.orca.config.executable = '/Applications/orca.app/Contents/MacOS/orca'
pio.write_html(fig, f"{save_name}.html")
pio.write_image(fig, f"{save_name}.png")

# 作成したグラフにHTMLコードを保存
html_code = fig.to_html(include_plotlyjs='cdn', full_html=False)
with open(f"{save_name}.txt", mode='w') as f:
    f.write(html_code)
# 株価のデータ
df = pd.DataFrame(dict(a=[1, 3, 2], b=[3, 2, 1]))
print(df)
#    a  b
# 0  1  3
# 1  3  2
# 2  2  1

plotlyの場合はデフォルトで積み上げ式の棒グラフが作成される。これを横並びにするにはfig.update_layout(barmode='group')と棒グラフの種類を変更する必要がる。

棒グラフを積み上げ式のままでいいのであれば、barmodeを変更する必要はない。後でグラフ化する。

# pandasで作成するプロットの種類をplotlyに変更
pd.options.plotting.backend = 'plotly'
fig = df.plot.bar()

# 積み上げ式ではなく、横並びにする場合はbarmode='group'
fig.update_layout(barmode='group')

最終的なグラフ部分のコードは以下。意外とシンプル。

# グラフ化

# pandasで作成するプロットの種類をplotlyに変更
pd.options.plotting.backend = 'plotly'
fig = df.plot.bar()

# 積み上げ式ではなく、横並びにする場合はbarmode='group'
fig.update_layout(barmode='group')
# グラフ全体とホバーのフォントサイズ変更
fig.update_layout(font_size=20, hoverlabel_font_size=20)
fig.show()

# グラフ保存
prefix = 'dfplot-plotly'  # 保存ファイル名の接頭辞
save_name = f"{prefix}_bar"
pio.orca.config.executable = '/Applications/orca.app/Contents/MacOS/orca'
pio.write_html(fig, f"{save_name}.html")
pio.write_image(fig, f"{save_name}.png")

積み上げ式の棒グラフを作成


積み上げ式の棒グラフの作成は簡単。先ほどの横並びの棒グラフのコードからfig.update_layout(barmode='group')をコメントアウトするだけ。

Plotly公式の「Python Figure Reference: layout」のbarmodeの解説ではデフォルトはgroupだが、なぜかstack(積み上げ式)がデフォルトとして適用される。

import pandas as pd
import plotly.express as px
import plotly.io as pio

df = pd.DataFrame(dict(a=[1, 3, 2], b=[3, 2, 1]))
print(df)
#    a  b
# 0  1  3
# 1  3  2
# 2  2  1

# pandasで作成するプロットの種類をplotlyに変更
pd.options.plotting.backend = 'plotly'
fig = df.plot.bar()

# # 積み上げ式ではなく、横並びにする場合はbarmode='group'
# fig.update_layout(barmode='group')
# グラフ全体とホバーのフォントサイズ変更
fig.update_layout(font_size=20, hoverlabel_font_size=20)
# fig.show()

# グラフ保存
prefix = 'dfplot-plotly'  # 保存ファイル名の接頭辞
save_name = f"{prefix}_bar_stack"
pio.orca.config.executable = '/Applications/orca.app/Contents/MacOS/orca'
pio.write_html(fig, f"{save_name}.html")
pio.write_image(fig, f"{save_name}.png")

水平の棒グラフ


棒が横向きとなる水平の棒グラフはdf.plot.barh()で描画可能。hはhorizontalの略だろう。

基本的にdf.plot.bar()と同じ考え方でグラフを作成することができる。ここではfig.update_layout(barmode='group')として横並びの棒グラフを作成した。

import pandas as pd
import plotly.express as px
import plotly.io as pio

# 水平の棒グラフ

# 株価のデータ
df = pd.DataFrame(dict(a=[1, 3, 2], b=[3, 2, 1]))
print(df)
#    a  b
# 0  1  3
# 1  3  2
# 2  2  1

print(' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -')
# グラフ化

# pandasで作成するプロットの種類をplotlyに変更
pd.options.plotting.backend = 'plotly'
fig = df.plot.barh()

# 積み上げ式ではなく、横並びにする場合はbarmode='group'
fig.update_layout(barmode='group')
# グラフ全体とホバーのフォントサイズ変更
fig.update_layout(font_size=20, hoverlabel_font_size=20)
fig.show()

# グラフ保存
prefix = 'dfplot-plotly'  # 保存ファイル名の接頭辞
save_name = f"{prefix}_barh"
pio.orca.config.executable = '/Applications/orca.app/Contents/MacOS/orca'
pio.write_html(fig, f"{save_name}.html")
pio.write_image(fig, f"{save_name}.png")

facet_rowでサブプロット


最後にサブプロット系の解説を行う。ただし、df.plot()で作成できるサブプロットは通常のサブプロットとは異なり、facetというタイプ。

facetは同じ種類の軸で作成されるサブプロットのグラフのこと。上のグラフの例だと同じ縦軸variable(ここでは株価)に対してサブプロットしている。

facetのプロットは主にPlotlypxで使われるプロットの方法。facetgoでのサブプロットについては以下の記事で詳しく解説している。

【plotly&make_subplots】pythonのplotlyで複数グラフを1つの画像に描く

続きを見る

【px&facet】plotly.expressでsubplotsを描く

続きを見る

import pandas as pd
import plotly.express as px
import plotly.io as pio

# subplot(facet)を作成

# 株価のデータ
df = px.data.stocks()

# 横軸が日付になるようにインデックスを設定
# データの型が異なるのでplotlyのプロット時にエラー
# ValueError: Plotly Express cannot process wide-form data with columns of different type.
df = df.set_index('date')
print(df)
#                 GOOG      AAPL      AMZN        FB      NFLX      MSFT
# date
# 2018-01-01  1.000000  1.000000  1.000000  1.000000  1.000000  1.000000
# 2018-01-08  1.018172  1.011943  1.061881  0.959968  1.053526  1.015988
# 2018-01-15  1.032008  1.019771  1.053240  0.970243  1.049860  1.020524
# 2018-01-22  1.066783  0.980057  1.140676  1.016858  1.307681  1.066561
# 2018-01-29  1.008773  0.917143  1.163374  1.018357  1.273537  1.040708
# ...              ...       ...       ...       ...       ...       ...
# 2019-12-02  1.216280  1.546914  1.425061  1.075997  1.463641  1.720717
# 2019-12-09  1.222821  1.572286  1.432660  1.038855  1.421496  1.752239
# 2019-12-16  1.224418  1.596800  1.453455  1.104094  1.604362  1.784896
# 2019-12-23  1.226504  1.656000  1.521226  1.113728  1.567170  1.802472
# 2019-12-30  1.213014  1.678000  1.503360  1.098475  1.540883  1.788185

# [105 rows x 6 columns]

print(' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -')
# グラフ化

# pandasで作成するプロットの種類をplotlyに変更
pd.options.plotting.backend = 'plotly'
# facet_rowでサブプロットにしたい変数を選択
fig = df.plot(facet_row='variable')

# グラフ全体とホバーのフォントサイズ変更
fig.update_layout(font_size=20, hoverlabel_font_size=20)
# グラフの高さを変更
fig.update_layout(height=1200)
fig.show()

# グラフ保存
prefix = 'dfplot-plotly'  # 保存ファイル名の接頭辞
save_name = f"{prefix}_facet_row"
pio.orca.config.executable = '/Applications/orca.app/Contents/MacOS/orca'
pio.write_html(fig, f"{save_name}.html")
pio.write_image(fig, f"{save_name}.png")

縦軸ラベルを変更


facet_rowでサブプロットっぽいグラフを作成できたが、縦軸がvariableでわかりづらい。ということで、ここでは縦軸のラベルを変更する。

fig.update_layoutyaxis_titleとすることで縦軸ラベルを変更することが可能。しかし、サブプロットの場合はそれぞれのグラフがy, y1, y2と名称が異なるのでそれぞれで指定する必要がある。

上のグラフの例ではyy2について縦軸ラベルを変更した。すると一番下のMSFTがy、その上のNFLXがy2に対応していることがわかる。y3以降も同様に指定可能。

データフレームではこれらは一番最後にくるので、データフレームの並びとy, y2, ...の並びが逆になることに注意。

import pandas as pd
import plotly.express as px
import plotly.io as pio

# 縦軸ラベルを変更

# 株価のデータ
df = px.data.stocks()
print(df)
#                 GOOG      AAPL      AMZN        FB      NFLX      MSFT
# date
# 2018-01-01  1.000000  1.000000  1.000000  1.000000  1.000000  1.000000
# 2018-01-08  1.018172  1.011943  1.061881  0.959968  1.053526  1.015988
# 2018-01-15  1.032008  1.019771  1.053240  0.970243  1.049860  1.020524
# 2018-01-22  1.066783  0.980057  1.140676  1.016858  1.307681  1.066561
# 2018-01-29  1.008773  0.917143  1.163374  1.018357  1.273537  1.040708
# ...              ...       ...       ...       ...       ...       ...
# 2019-12-02  1.216280  1.546914  1.425061  1.075997  1.463641  1.720717
# 2019-12-09  1.222821  1.572286  1.432660  1.038855  1.421496  1.752239
# 2019-12-16  1.224418  1.596800  1.453455  1.104094  1.604362  1.784896
# 2019-12-23  1.226504  1.656000  1.521226  1.113728  1.567170  1.802472
# 2019-12-30  1.213014  1.678000  1.503360  1.098475  1.540883  1.788185

# [105 rows x 6 columns]

# pandasで作成するプロットの種類をplotlyに変更
pd.options.plotting.backend = 'plotly'
# facet_rowでサブプロットにしたい変数を選択
fig = df.plot(facet_row='variable')

# グラフ全体とホバーのフォントサイズ変更
fig.update_layout(font_size=20, hoverlabel_font_size=20)
# グラフの高さを変更
fig.update_layout(height=1200)
#y, y2の縦軸ラベルを変更
fig.update_layout(yaxis_title='y', yaxis2_title='y2')
# fig.show()

# グラフ保存
prefix = 'dfplot-plotly'  # 保存ファイル名の接頭辞
save_name = f"{prefix}_facet_row_yaxistitle"
pio.orca.config.executable = '/Applications/orca.app/Contents/MacOS/orca'
pio.write_html(fig, f"{save_name}.html")
pio.write_image(fig, f"{save_name}.png")

facetで軸の共有を解除


先ほどのfacetのグラフでは、全てのグラフの横軸が共通だった。レイアウトのxaxisに対してshowticklabels=Trueとすることで、共通の軸を解除することができる。

しかし、facetのグラフの場合は複数のグラフを作っているので、それぞれの軸(xaxisxaxis2、...)でshowticklabels=Trueとする必要がある。

forで1軸ずつ変更することももちろん可能だが、fig.for_each_xaxislambda式を使うことで1行で処理を書くことが可能。

# 各グラフの横軸ラベルを表示
fig.for_each_xaxis(lambda x: x.update(showticklabels=True))

lambda式のxfor xxに相当するイメージ。各xaxisxaxis.update(showticklabels=True))のように変更している。

この1行を追加するだけで上のグラフのように共通の軸を削除し、各グラフに横軸を追加することが可能になる。

import pandas as pd
import plotly.express as px
import plotly.io as pio

# subplotで軸を共有を解除

# 株価のデータ
df = px.data.stocks()

# 横軸が日付になるようにインデックスを設定
# データの型が異なるのでplotlyのプロット時にエラー
# ValueError: Plotly Express cannot process wide-form data with columns of different type.
df = df.set_index('date')
print(df)
#                 GOOG      AAPL      AMZN        FB      NFLX      MSFT
# date
# 2018-01-01  1.000000  1.000000  1.000000  1.000000  1.000000  1.000000
# 2018-01-08  1.018172  1.011943  1.061881  0.959968  1.053526  1.015988
# 2018-01-15  1.032008  1.019771  1.053240  0.970243  1.049860  1.020524
# 2018-01-22  1.066783  0.980057  1.140676  1.016858  1.307681  1.066561
# 2018-01-29  1.008773  0.917143  1.163374  1.018357  1.273537  1.040708
# ...              ...       ...       ...       ...       ...       ...
# 2019-12-02  1.216280  1.546914  1.425061  1.075997  1.463641  1.720717
# 2019-12-09  1.222821  1.572286  1.432660  1.038855  1.421496  1.752239
# 2019-12-16  1.224418  1.596800  1.453455  1.104094  1.604362  1.784896
# 2019-12-23  1.226504  1.656000  1.521226  1.113728  1.567170  1.802472
# 2019-12-30  1.213014  1.678000  1.503360  1.098475  1.540883  1.788185

# [105 rows x 6 columns]

print(' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -')
# グラフ化

# pandasで作成するプロットの種類をplotlyに変更
pd.options.plotting.backend = 'plotly'
fig = df.plot(facet_row='variable')

# 各グラフの横軸ラベルを表示
fig.for_each_xaxis(lambda x: x.update(showticklabels=True))
# グラフ全体とホバーのフォントサイズ変更
fig.update_layout(font_size=20, hoverlabel_font_size=20)
# グラフの高さを変更
fig.update_layout(height=1200)
fig.show()

# グラフ保存
prefix = 'dfplot-plotly'  # 保存ファイル名の接頭辞
save_name = f"{prefix}_facet_row_showticklabels"
pio.orca.config.executable = '/Applications/orca.app/Contents/MacOS/orca'
pio.write_html(fig, f"{save_name}.html")
pio.write_image(fig, f"{save_name}.png")

facet_col_wrapでサブプロットの列数を変更


最後にサブプロットの配置を変更する方法を解説する。列数の変更は’facet_col’, ‘facet_col_wrap’で行う。先ほどはfacet_rowで行について指定したが、今度はcolで列指定。

【px&facet】plotly.expressでsubplotsを描く

続きを見る

facet_col_wrapは列の数を指定する引数で、上のグラフだとfacet_col_wrap=2で2列としている。なお、facet_col_wrapfacet_rowと併用すると無効化される。後述。

facet_colにはfacet_rowと同様、facet_col='variable'としてvariableを指定するだけ。

import pandas as pd
import plotly.express as px
import plotly.io as pio

# サブプロットのグラフの配置を変更

# 株価のデータ
df = px.data.stocks()

# 横軸が日付になるようにインデックスを設定
# データの型が異なるのでplotlyのプロット時にエラー
# ValueError: Plotly Express cannot process wide-form data with columns of different type.
df = df.set_index('date')
print(df)
#                 GOOG      AAPL      AMZN        FB      NFLX      MSFT
# date
# 2018-01-01  1.000000  1.000000  1.000000  1.000000  1.000000  1.000000
# 2018-01-08  1.018172  1.011943  1.061881  0.959968  1.053526  1.015988
# 2018-01-15  1.032008  1.019771  1.053240  0.970243  1.049860  1.020524
# 2018-01-22  1.066783  0.980057  1.140676  1.016858  1.307681  1.066561
# 2018-01-29  1.008773  0.917143  1.163374  1.018357  1.273537  1.040708
# ...              ...       ...       ...       ...       ...       ...
# 2019-12-02  1.216280  1.546914  1.425061  1.075997  1.463641  1.720717
# 2019-12-09  1.222821  1.572286  1.432660  1.038855  1.421496  1.752239
# 2019-12-16  1.224418  1.596800  1.453455  1.104094  1.604362  1.784896
# 2019-12-23  1.226504  1.656000  1.521226  1.113728  1.567170  1.802472
# 2019-12-30  1.213014  1.678000  1.503360  1.098475  1.540883  1.788185

# [105 rows x 6 columns]

print(' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -')
# facet_col_wrapでfacetの列数を変更

# pandasで作成するプロットの種類をplotlyに変更
pd.options.plotting.backend = 'plotly'

# なぜかfacet_col_wrapが効かない
fig = df.plot(facet_col='variable', facet_col_wrap=2)

# グラフ全体とホバーのフォントサイズ変更
fig.update_layout(font_size=20, hoverlabel_font_size=20)
fig.show()

# グラフ保存
prefix = 'dfplot-plotly'  # 保存ファイル名の接頭辞
save_name = f"{prefix}_facet_col_wrap"
pio.orca.config.executable = '/Applications/orca.app/Contents/MacOS/orca'
pio.write_html(fig, f"{save_name}.html")
pio.write_image(fig, f"{save_name}.png")

facet_rowfacet_col_wrapの併用はdomainで解決


fig = df.plot(facet_col='variable', facet_col_wrap=2)とすることでサブプロットの列数を変更できた。

ここでfacet_colの代わりにfacet_rowを使ってみる。んだが、実はfacet_rowfacet_col_wrapの併用はできない。facet_col_wrapの列数指定が無効になる。

ということで、x軸・y軸の引数domainを使って、各企業のグラフの位置を(x, y)の相対位置で指定する。位置関係については以下の画像参照。

GOOGに該当するaxisが右下に来るようにdoaminx, yの値を調節する必要がある。

なお、xの最大値を1としてしまうとグラフ右側のfacetの凡例と被ってしまう。したがって、ここではxの最大値は0.95に調節している。

import pandas as pd
import plotly.express as px
import plotly.io as pio

# pandasで作成するプロットの種類をplotlyに変更
pd.options.plotting.backend = 'plotly'

# なぜかfacet_col_wrapが効かない
fig = df.plot(facet_row='variable', facet_col_wrap=2)

# 右上がx1, y1で左上がx2, y2
fig.update_layout(
    xaxis_domain=(0.5, 1),  # MSFT
    xaxis2_domain=(0, 0.45),  # NFLX
    xaxis3_domain=(0.5, 0.95),  # FB
    xaxis4_domain=(0, 0.45),  # AMZN
    xaxis5_domain=(0.5, 0.95),  # AAPL
    xaxis6_domain=(0, 0.45),  # GOOG

    yaxis_domain=(0, 0.3),  # MSFT
    yaxis2_domain=(0, 0.3),  # NFLX
    yaxis3_domain=(0.33, 0.63),  # FB
    yaxis4_domain=(0.33, 0.63),  # AMZN
    yaxis5_domain=(0.66, 1),  # AAPL
    yaxis6_domain=(0.66, 1),  # GOOG
)

# グラフ全体とホバーのフォントサイズ変更
fig.update_layout(font_size=20, hoverlabel_font_size=20)
# グラフの高さを変更
fig.update_layout(height=1200)
fig.show()

# グラフ保存
prefix = 'dfplot-plotly'  # 保存ファイル名の接頭辞
save_name = f"{prefix}_facet_row_domain"
pio.orca.config.executable = '/Applications/orca.app/Contents/MacOS/orca'
pio.write_html(fig, f"{save_name}.html")
pio.write_image(fig, f"{save_name}.png")

pandasから即グラフ化

ということで、今回はpandasからすぐにグラフを作成できるdf.plot()pd.options.plotting.backend = 'plotly’Plotly形式でグラフ化する方法について解説した。

Plotlymatplotlibとは異なる書き方が必要となるため、とっつきにくいと感じる人も多いだろう。しかし、本記事のdf.plot()ですぐにプロットできるとまた印象が変わるに違いない。

matplotlibは飽きた、もっと高機能なグラフを作成したいと思う人への一助となれば幸いだ。

関連記事

【plt&pandas】df.plot()でmatplotlibのグラフを作成

続きを見る

【plotly&Scattergl】大量のデータをplotlyで軽くグラフ化

続きを見る

【px&facet】plotly.expressでsubplotsを描く

続きを見る

【plotly&px.scatter】pxでの散布図の描き方

続きを見る

【plotly&go.Scatter】plotlyの散布図グラフの描き方

続きを見る

【plotly&pattern】棒グラフとかのパターンまとめ

続きを見る

【plt&棒グラフ】pythonのmatplotlibで棒グラフを作成してみる

続きを見る

【plolty&棒グラフ】px.barでバーチャートを作成

続きを見る

【collections.Counter】配列の要素を要素名と個数で勝手に集計

続きを見る

ガジェット

2023/9/18

【デスクツアー2022下半期】モノは少なく、でも効率的に Desk Updating #0

今回はガジェットブロガーなのにデスク環境を構築していない執筆者の ...

ライフハック

2023/9/16

【Audible vs YouTube Premium】耳で聴く音声学習コンテンツを比較

ワイヤレスイヤホンが普及し耳で学習することへのハードルが格段に下 ...

完全ワイヤレスイヤホン(TWS)

2023/9/18

【SENNHEISER MOMENTUM True Wireless 3レビュー】全てが整ったイヤホン

今回は高音質・高機能なSENNHEISERのフラグシップ完全ワイヤレスイヤホン「SENNH ...

ライフハック

2023/3/11

【YouTube Premiumとは】メリットしかないから全員入れ

今回はYouTube Premiumを実際に使ってみてどうなのか、どんなメリット/デメリット ...

マウス

2023/8/17

【Logicool MX ERGOレビュー】疲れない作業効率重視トラックボールマウス

こんな人におすすめ トラックボールマウスの王道Logicool MX ERGOが気になるけどऩ ...

ベストバイ

2023/9/18

【ベストバイ2022】今年買って良かったモノのトップ10

2022年ベストバイ この1年を振り返って執筆者は何を買ったのか。ガジェッ& ...

スマホ

2023/1/15

【楽天モバイル×povo2.0の併用】月1,000円の保険付きデュアルSIM運用

こんな人におすすめ 楽天モバイルとpovo2.0のデュアルSIM運用って実際のとこ ...

マウス

2023/9/16

【Logicool MX ERGO vs MX Master 3】ERGOをメインにした決定的な理由

こんな疑問・お悩みを持っている人におすすめ 執筆者はLogicoolのハイエンӠ ...

macOSアプリケーション

2022/9/30

【Chrome拡張機能】便利で効率的に作業できるおすすめの拡張機能を18個紹介する

こんな人におすすめ Chromeの拡張機能を入れたいけど、調べても同じような ...

macOSアプリケーション

2023/5/3

【Automator活用術】Macで生産性を上げる作業の自動化術

今回はMacに標準でインストールされているアプリ「Automator」を使ってできる ...

Pythonを学びたいけど独学できる時間なんてない人へのすゝめ

執筆者は大学の研究室・大学院にて独学でPythonを習得した。

でも社会人になったら独学で行うには時間も体力もなくて大変だ。

時間がない社会人だからこそプロの教えを乞うのが効率的。

ここでは色んなタイプに合ったプログラミングスクールの紹介をする。

  • この記事を書いた人

メガネ

Webエンジニア駆け出し。独学のPythonで天文学系の大学院を修了。常時金欠のガジェット好きでM2 Pro MacBook Pro(30万円) x Galaxy S22 Ultra(17万円)使いの狂人。自己紹介と半生→変わって楽しいの繰り返しレビュー依頼など→お問い合わせ運営者情報、TwitterX@m_ten_pa、 YouTube@megatenpa、 Threads@megatenpa

-Pythonでの比較
-, , , , ,