Plotly

【Pythonで業務改善】複数y軸グラフ+管理線付きグラフ作成

複数のY軸を持つグラフの作成方法と管理線の追加方法について解説します。

for文を使って複数のグラフを数行で作る例も紹介するのでかなり実践的な内容になるかと思います。

今回紹介するグラフ可視化ツールのplotlyでは軸をドラッグ&ドロップで操作したり、プロット点にポインタを合わせることでデータの情報を表示できたり、直感的に動かすことができるので複数のy軸があっても相手に伝わりやすいグラフを作成できます。

シンプルな複数y軸グラフ

fig = make_subplots(rows=ncols, cols=1, shared_xaxes=True)

shared_xaxes=Trueとすることで複数グラフのx軸を共有とすることができます。

plotlyでは軸の範囲をマウスで拡大・縮小できるので使い勝手やデータの解析にも便利です。

for文を使って項目の数だけグラフを整列させます。

import plotly.graph_objects as go
import plotly.io as pio
from plotly.subplots import make_subplots
import pandas as pd
import plotly.express as px

pio.templates.default = "plotly_white"
df = px.data.gapminder().query("country=='Japan'")
df = df.set_index('year')
cols = df.columns[2:5]
ncols = len(cols)

fig = make_subplots(rows=ncols, cols=1, shared_xaxes=True)

for i, col in enumerate(cols, start=1):
    fig.add_trace(go.Scatter(x=df[col].index, y=df[col].values), row=i, col=1)
    
fig.show()

管理線を追加した複数y軸グラフ

管理線に使用する値はあらかじめデータフレーム内に設置しておくと楽ですが、今回はあとから追加する場合の想定で行います。

コードは分かりやすさを重視してあえて簡単な表現にしています。

rowとcolが同じ値になれば同様のグラフ内に管理線が追加できます。

後半のfor文2つ分が管理線を追加している部分です。

import plotly.graph_objects as go
import plotly.io as pio
from plotly.subplots import make_subplots
import pandas as pd
import plotly.express as px

pio.templates.default = "plotly_white"
df = px.data.gapminder().query("country=='Japan'")
df = df.set_index('year')

#下限の管理値
df['管理値1']=60
df['管理値3']=80000000
df['管理値5']=0

#上限の管理値
df['管理値2']=90
df['管理値4']=140000000
df['管理値6']=40000

cols = df.columns[2:5]
cols_kanri_min = df.columns[7:10]
cols_kanri_max = df.columns[10:13]
ncols = len(cols)

fig = make_subplots(rows=ncols, cols=1, shared_xaxes=True)

for i, col in enumerate(cols, start=1):
    fig.add_trace(go.Scatter(x=df[col].index, y=df[col].values), row=i, col=1)
for i, col in enumerate(cols_kanri_min, start=1):    
    fig.add_trace(go.Scatter(x=df[col].index, y=df[col].values, mode='lines',line=dict(color='rgb(51, 51, 51)',width=4, dash='dot')), row=i, col=1)
for i, col in enumerate(cols_kanri_max, start=1):    
    fig.add_trace(go.Scatter(x=df[col].index, y=df[col].values, mode='lines',line=dict(color='rgb(51, 51, 51)',width=4, dash='dot')), row=i, col=1)    

fig.show()

Listを使って項目毎に自動でグラフを作成する(実践的)

最後はおまけですが、グラフを作成する部分のfor文よりも上位の部分にリストで作成された項目を順次選択するfor文を組むと項目別の複数グラフがリスト分作成されます。

import plotly.graph_objects as go
import plotly.io as pio
from plotly.subplots import make_subplots
import pandas as pd
import plotly.express as px

pio.templates.default = "plotly_white"

df = px.data.gapminder()
list=[]
list=('Japan','China')
for t in list:
    df_c=df[(df['country']==t)]
    df_c = df_c.set_index('year')

    #下限の管理値
    df_c['管理値1']=60
    df_c['管理値3']=80000000
    df_c['管理値5']=0

    #上限の管理値
    df_c['管理値2']=90
    df_c['管理値4']=140000000
    df_c['管理値6']=40000

    cols = df_c.columns[2:5]
    cols_kanri_min = df_c.columns[7:10]
    cols_kanri_max = df_c.columns[10:13]
    ncols = len(cols)

    fig = make_subplots(rows=ncols, cols=1, shared_xaxes=True)

    for i, col in enumerate(cols, start=1):
        fig.add_trace(go.Scatter(x=df_c[col].index, y=df_c[col].values), row=i, col=1)
    for i, col in enumerate(cols_kanri_min, start=1):    
        fig.add_trace(go.Scatter(x=df_c[col].index, y=df_c[col].values, mode='lines',line=dict(color='rgb(51, 51, 51)',width=4, dash='dot')), row=i, col=1)
    for i, col in enumerate(cols_kanri_max, start=1):    
        fig.add_trace(go.Scatter(x=df_c[col].index, y=df_c[col].values, mode='lines',line=dict(color='rgb(51, 51, 51)',width=4, dash='dot')), row=i, col=1)    

    fig.show()

    pio.write_html(fig,file=f'複数軸-3-{t}.html')

一つ目のグラフ(Japan)

二つ目のグラフ(China)

以上で解説は終わりです。

Plotlyに関する書籍紹介

↓Plotlyについて学べる数少ない参考書です。

ABOUT ME
Mickey@コーヒー好きエンジニア
【製造業×プログラミング×AI】Python/VBAを活用した業務改善、Streamlit/Plotlyを活用したWebアプリ開発について初心者向けに発信中|Wordpressブログを運営しながらHTML/CSSの勉強中|趣味は自家焙煎コーヒー作り|noteでは焙煎理論を発信
【製造×プログラミング×AI】
Mickey@コーヒー好きエンジニア
【製造業×プログラミング×AI】ロボット×画像処理×AI×3現主義が得意な生産技術者|Python/VBAを活用した業務改善、Streamlit/Plotly/PySimpleGUIなどを活用したアプリ開発について初心者向けに発信中|趣味は自家焙煎コーヒー作り|noteでは焙煎理論を発信|iOSアプリ開発も始めました
\ Follow me /