【完全ガイド】plotlyで作るインタラクティブグラフ

ソニック

静的グラフから卒業する

「Excelのグラフはもう古い」「データを動的に見せたい」

そんな悩みを解決するのが、Pythonのライブラリ「plotly(プロットリー)」です。

plotlyを使えば、マウスホバーで詳細表示、ズーム、フィルター切替などのインタラクティブ機能を備えたグラフが、たった数行のコードで作れます。Excelのグラフでは表現できなかった「動的な可視化」が、誰でも実現できるのです。

この記事では、plotlyの基本から実務で使えるグラフのテクニックまで、コピペで使えるコード付きで完全解説します。

第1章|なぜplotlyなのか|matplotlibとの違い

目次

matplotlibはなぜ「物足りない」のか

Pythonでグラフを描く定番ライブラリは matplotlib です。しかし、matplotlibは「静的なグラフ画像」を出力するため、以下の限界があります。

  • マウスホバーで値の詳細が見えない
  • ズーム・パン操作ができない
  • 動的にフィルターを切り替えられない
  • Webブラウザで操作できない

経営者や同僚に「数字を物語る」資料を作るには、これらの限界が大きな壁になります。

plotlyが提供する「3つの革命」

  1. インタラクティブ性:マウス操作で詳細表示・拡大・絞り込み
  2. Webブラウザネイティブ:HTML出力で誰でも閲覧可能
  3. 美しいデザイン:デフォルトでプロ品質の見た目

どう使い分けるか

用途matplotlibplotly
論文・レポート用画像
ダッシュボード
Webブラウザでの共有△(画像のみ)
経営者向けプレゼン
printout(紙印刷)

「動かして見せる」場面ではplotly、「印刷して見せる」場面ではmatplotlibと使い分けるのが理想です。

第2章|環境準備(uv環境前提)

この記事は、uv環境でPythonを使う前提で進めます。まだuvをインストールしていない方は、別記事「【完全版】uv入門」をご覧ください。

必要なライブラリ

uv add plotly pandas
  • plotly:インタラクティブグラフのメインライブラリ
  • pandas:データ処理(おなじみ)

第3章|基本のグラフ|棒・折れ線・円

plotlyの基本グラフから始めます。plotlyには「plotly.express」(簡単版)と「plotly.graph_objects」(高機能版)の2種類がありますが、まずはexpressから入るのが最速です。

棒グラフ

import plotly.express as px
import pandas as pd

df = pd.DataFrame({
    "月": ["1月", "2月", "3月", "4月", "5月"],
    "売上": [120, 150, 180, 165, 200]
})

fig = px.bar(df, x="月", y="売上", title="月別売上推移")
fig.show()

fig.show() でブラウザが自動で開き、インタラクティブな棒グラフが表示されます。マウスホバーで値の詳細、ドラッグでズームができます。

折れ線グラフ

fig = px.line(df, x="月", y="売上", title="月別売上推移", markers=True)
fig.show()

markers=True にすると、各データ点にマーカー(丸印)が表示されます。

円グラフ

fig = px.pie(df, names="月", values="売上", title="月別売上の構成比")
fig.show()

散布図

df2 = pd.DataFrame({
    "広告費": [10, 20, 30, 40, 50],
    "売上": [100, 180, 250, 320, 400],
    "店舗": ["A店", "A店", "B店", "B店", "C店"]
})

fig = px.scatter(df2, x="広告費", y="売上", color="店舗", title="広告費と売上の関係")
fig.show()

第4章|インタラクティブ機能の本領発揮

plotlyの真骨頂は、グラフが「動く」こと。マウス操作で動的にデータを切り替えられます。

ホバー表示のカスタマイズ

マウスホバーで表示される情報を、自由にカスタマイズできます。

import plotly.express as px
import pandas as pd

df = pd.DataFrame({
    "月": ["1月", "2月", "3月"],
    "売上": [120, 150, 180],
    "利益率": [0.20, 0.25, 0.30],
    "店舗数": [10, 12, 15]
})

fig = px.bar(
    df, x="月", y="売上", title="月別売上",
    hover_data=["利益率", "店舗数"]
)
fig.show()

マウスを各バーに当てると、利益率と店舗数も同時に表示されます。

ドロップダウンでの切替(高度)

ドロップダウンメニューで、表示するデータを切り替えられます。

import plotly.graph_objects as go
import pandas as pd

df = pd.DataFrame({
    "月": ["1月", "2月", "3月", "4月"],
    "売上": [120, 150, 180, 165],
    "利益": [30, 40, 50, 45]
})

fig = go.Figure()
fig.add_trace(go.Bar(x=df["月"], y=df["売上"], name="売上", visible=True))
fig.add_trace(go.Bar(x=df["月"], y=df["利益"], name="利益", visible=False))

fig.update_layout(
    title="売上・利益の切替",
    updatemenus=[{
        "buttons": [
            {"label": "売上を表示", "method": "update", "args": [{"visible": [True, False]}]},
            {"label": "利益を表示", "method": "update", "args": [{"visible": [False, True]}]},
        ],
        "direction": "down",
        "showactive": True,
    }]
)
fig.show()

ドロップダウンで「売上」「利益」を切り替えながら表示できます。

アニメーション機能

時系列データを「再生」できるアニメーショングラフも作れます。

import plotly.express as px

df = px.data.gapminder()

fig = px.scatter(
    df, x="gdpPercap", y="lifeExp",
    animation_frame="year", animation_group="country",
    size="pop", color="continent", hover_name="country",
    log_x=True, size_max=55,
    title="GDP vs 平均寿命の推移(年別アニメーション)"
)
fig.show()

再生ボタンを押すと、年ごとに点の位置が動きます。プレゼンで圧倒的インパクトを生みます。

第5章|複合グラフ|2軸グラフ・サブプロット

実務では「売上と利益率」のように、単位の違う2つのデータを1つのグラフで見せたいことがあります。

2軸グラフ

import plotly.graph_objects as go
import pandas as pd
from plotly.subplots import make_subplots

df = pd.DataFrame({
    "月": ["1月", "2月", "3月", "4月", "5月"],
    "売上": [120, 150, 180, 165, 200],
    "利益率": [0.18, 0.22, 0.25, 0.20, 0.30]
})

fig = make_subplots(specs=[[{"secondary_y": True}]])

# 主軸:売上(棒グラフ)
fig.add_trace(
    go.Bar(x=df["月"], y=df["売上"], name="売上"),
    secondary_y=False,
)

# 副軸:利益率(折れ線)
fig.add_trace(
    go.Scatter(x=df["月"], y=df["利益率"], name="利益率", mode="lines+markers"),
    secondary_y=True,
)

fig.update_layout(title="売上と利益率の推移")
fig.update_yaxes(title_text="売上(万円)", secondary_y=False)
fig.update_yaxes(title_text="利益率", secondary_y=True)

fig.show()

売上は棒グラフ、利益率は折れ線で同じグラフ上に表示できます。

サブプロット(複数グラフを並べる)

from plotly.subplots import make_subplots
import plotly.graph_objects as go

fig = make_subplots(rows=1, cols=2, subplot_titles=("売上", "利益"))

fig.add_trace(
    go.Bar(x=["1月", "2月", "3月"], y=[120, 150, 180]),
    row=1, col=1
)
fig.add_trace(
    go.Bar(x=["1月", "2月", "3月"], y=[30, 40, 50]),
    row=1, col=2
)

fig.update_layout(title="月別の売上と利益(並列表示)")
fig.show()

第6章|デザインを整える|テンプレ・色・タイトル

テンプレート(デザインの一括変更)

plotlyには複数のデザインテンプレートが用意されています。

import plotly.express as px

fig = px.bar(df, x="月", y="売上")

# テンプレートを変更
fig.update_layout(template="plotly_white")
# fig.update_layout(template="plotly_dark")
# fig.update_layout(template="seaborn")
# fig.update_layout(template="simple_white")

fig.show()

色をカスタマイズ

import plotly.express as px

# 単色指定
fig = px.bar(df, x="月", y="売上", color_discrete_sequence=["#0066ff"])

# 複数色(マイペースブログの青系)
colors = ["#003d99", "#0066ff", "#4d94ff", "#e8f1ff"]
fig = px.bar(df, x="月", y="売上", color="月", color_discrete_sequence=colors)

fig.show()

タイトル・軸ラベルの装飾

fig.update_layout(
    title={
        "text": "月別売上推移",
        "x": 0.5,
        "font": {"size": 24, "color": "#0a1628"}
    },
    xaxis_title="月",
    yaxis_title="売上(万円)",
    font={"family": "Yu Gothic, sans-serif"}
)
fig.show()

第7章|HTMLで保存・共有する方法

plotlyのグラフは、HTMLファイルとして保存して共有できます。受け取った人はブラウザで開くだけで、インタラクティブ操作が可能です。

HTMLとして保存

fig.write_html("売上ダッシュボード.html")

これで「売上ダッシュボード.html」が作成されます。メール添付・社内共有・ダウンロード提供などに使えます。

画像(PNG)として保存

印刷用や報告書用に静止画として書き出すこともできます。

# 追加ライブラリが必要
# uv add kaleido

fig.write_image("売上グラフ.png", width=1200, height=600)

※PNG出力には kaleido というライブラリが別途必要です。

streamlit と組み合わせる

streamlitダッシュボードに組み込むと、plotlyの威力が最大化されます。

import streamlit as st
import plotly.express as px

fig = px.bar(df, x="月", y="売上")
st.plotly_chart(fig)

streamlit については別記事「【完全ガイド】streamlitで作る経営ダッシュボード入門」で詳しく解説しています。

第8章|つまずき対処&まとめ

よくあるトラブル

トラブル1:グラフが表示されない

原因:

環境によっては fig.show() でブラウザが自動で開かない場合があります。

対処:

# HTMLファイルとして保存して、手動で開く
fig.write_html("graph.html")

トラブル2:日本語が文字化け

対処:

fig.update_layout(font={"family": "Yu Gothic, Meiryo, sans-serif"})

トラブル3:データ量が多くて重い

対処:

数万件以上のデータでは plotly.express ではなく plotly.graph_objects を使い、必要に応じてサンプリングします。

トラブル4:HTMLファイルが大きすぎる

対処:

HTMLファイルにplotly本体が埋め込まれて重くなる場合、CDN指定でファイルサイズを削減できます。

fig.write_html("graph.html", include_plotlyjs="cdn")

この記事のまとめ

  • plotlyはインタラクティブなグラフを誰でも作れる革命的ライブラリ
  • plotly.express の数行で、棒・折れ線・円・散布図が作れる
  • ホバー・ドロップダウン・アニメーションで、データを動的に見せる
  • HTMLファイル保存で、誰でもブラウザで操作可能
  • streamlit と組み合わせれば、本格ダッシュボードに発展

FAQ

Q1. matplotlibの知識がないと使えませんか?

不要です。plotlyはmatplotlibとは別物として独立しています。むしろplotlyの方が文法がシンプルで、初心者に優しい設計です。

Q2. plotly.express と plotly.graph_objects、どちらを学ぶべきですか?

まずは plotly.express から始めましょう。9割の業務は express で対応できます。複雑な複合グラフを作る時にだけ graph_objects に手を出せばOKです。

Q3. HTMLファイルは社内で共有できますか?

はい、メール添付や共有ドライブで配布できます。受け取った人はブラウザで開くだけで、インタラクティブ操作が可能です。Excelファイルと違ってバージョン互換性も心配いりません。

Q4. データ量はどれくらいまで耐えられますか?

数千件なら問題なく動きます。数万〜数十万件でも工夫すれば対応可能ですが、重くなる場合はサンプリングや、サーバー側でのレンダリング(Dash等)を検討します。

Q5. streamlitとplotly、どちらを先に学ぶべきですか?

plotlyを先に学ぶのがおすすめです。グラフが作れるようになってから、それを並べる枠としてstreamlitを使うと、構造が理解しやすいです。

「動くグラフ」で、世界が広がる

plotlyを使えば、Excelのグラフでは表現できなかった「動的なデータ可視化」が、誰でも実現できます。

「数字を見せる」ではなく「数字を物語る」――そんなアウトプットを、ぜひ作ってみてください。

最新の解説記事は、新着記事から順次公開しています。X(旧Twitter)でも更新情報を発信していますので、ぜひフォローしてください。

この記事を書いた人

ソニック|バックオフィス7年目の業務効率化ブロガー。データサイエンス業務で日常的にplotlyを活用し、顧客レポート・ダッシュボード制作に従事。

→ 詳しいプロフィールはこちら→ はじめての方へ

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

コメント

コメントする

CAPTCHA


目次