Plotly(プロットリー)は、ズーム・ホバー・凡例クリックで操作できるグラフを作るオープンソースの可視化ライブラリです。Pythonでは import plotly.express as px の1行と関数1つでグラフができ、結果はブラウザやJupyterで動くHTMLとして表示されます。この記事では2026年10月時点の最新版 Plotly 7.1.0 を前提に、読み方と製品の全体像、つまずきやすいインストール、散布図・折れ線・ガントチャートのコード、7.0で消えた機能、Matplotlibとの使い分けを順に説明します。色の指定や画像出力の細部はPlotlyの色(color)指定と使い方|パレット一覧・v7の色書式・React・画像出力にまとめています。
まとめ:Plotlyの要点
- Plotlyは操作できるグラフを作るライブラリ。読み方は「プロットリー」。Python版のplotly.pyはJavaScriptのplotly.jsの上に作られ、どちらもMITライセンスで商用でも無料。
- 最新版は7.1.0(2026年9月15日)。
pip install plotlyだけではplotly.expressがImportErrorになるため、pip install "plotly[express]" pandasで入れる。 - 書き方の入口は
plotly.express(px)。散布図はpx.scatter、折れ線はpx.line、ガントチャートはpx.timeline。二軸・異種の組み合わせなど、pxで表現できない構成はplotly.graph_objectsで書く。 - 7.0で
create_ganttなどFigure Factoryの12関数とMapbox系の関数が削除された。古い記事のコードはそのままでは動かない。 - 人に触ってもらう図・Webに載せる図はPlotly、論文やPDFに貼る静的な図はMatplotlibが向く。
Plotlyとは:読み方と製品の全体像
Plotlyは、カナダのモントリオールを拠点とする同名の会社が開発するデータ可視化の製品群です(Plotly社の会社紹介)。中核のJavaScriptライブラリplotly.jsは、2015年11月17日のv1.0.0でMITライセンスのオープンソースとして公開されました(plotly.js v1.0.0のリリースノート)。それまでPlotly社の製品の内部で使われていた描画技術を公開したもので、現在のPython版もこのplotly.jsで描画しています。
公式ドキュメントはPython版を、40種類以上のグラフに対応したインタラクティブなオープンソースのライブラリと説明しています(Getting Started with Plotly in Python)。点に合わせると値が出るホバー、範囲を囲んだ拡大、凡例クリックでの系列の出し入れ、PNG保存ボタンが、追加のコードなしで付きます。
plotly.py・plotly.js・Dashの関係
「Plotly」は文脈によって指すものが変わります。検索で見かける名前を整理すると次のとおりです。
| 名前 | 中身 | 最新版(2026-10-27) | ライセンス |
|---|---|---|---|
| plotly.py | Python用ライブラリ(pip名はplotly) | 7.1.0 | MIT |
| plotly.js | 描画を担うJavaScriptライブラリ | 4.1.2 | MIT |
| Dash | PythonだけでWebアプリを作るフレームワーク | 4.4.1 | MIT |
| Dash Enterprise | Dashアプリの社内配備向け製品 | – | 有料 |
plotly.pyで作った図は、内部でplotly.js向けのJSONに変換されてブラウザで描かれます。7.1.0が同梱しているplotly.jsは4.1.1です(plotly.pyのCHANGELOG)。この記事で単に「Plotly」と書く場合はPython版を指します。グラフを部品にして画面全体を組むならPython Dashとは?4.4対応の使い方・コールバック・デプロイを動くコードで解説が続きの内容です。
Plotlyの料金と無料で使える範囲
plotly.py・plotly.js・DashはいずれもPyPIなどでMITライセンスとして配布されており、社内システムや商用サービスに組み込んでも利用料はかかりません。お金がかかるのは、Dashアプリを組織で配備・管理するDash Enterpriseのような運用向け製品です。グラフを作ってHTMLで共有するところまでなら、有料製品は不要です。
Plotlyで作れるグラフの種類
よく使うグラフはplotly.expressの関数1つに対応しています。7.1.0でpxが公開している描画関数は36個(補助関数のget_trendline_resultsを除く)です。
| グラフ | px の関数 | 主な用途 |
|---|---|---|
| 散布図 | px.scatter | 2変数の相関・分布 |
| 折れ線 | px.line | 時系列の推移 |
| 棒グラフ | px.bar | カテゴリの比較 |
| ヒストグラム | px.histogram | 度数分布 |
| 箱ひげ図 | px.box | ばらつき・外れ値 |
| ヒートマップ | px.imshow / px.density_heatmap | 行列・2次元の密度 |
| 3D散布図 | px.scatter_3d | 3変数の分布 |
| 塗り分け地図 | px.choropleth | 国・地域別の値 |
| 地図上の点 | px.scatter_map | 緯度経度の分布 |
| ガントチャート | px.timeline | 工程表・日程 |
どの関数も戻り値はFigureオブジェクトで、作った後にupdate_layoutやupdate_tracesで見た目を同じ書き方で調整できます。7.0ではベクトル場を矢印で描くquiverトレースも加わりました。
Plotly 7.1のインストールと依存パッケージ
公式の手順はpip install plotlyまたはconda install -c conda-forge plotlyです。plotly本体のPyPI上の要件はPython 3.8以上ですが、組み合わせるnumpyとpandasの最新版はそれより新しいPythonを要求します(2026年10月時点でnumpy 2.5.4はPython 3.12以上、pandas 3.1.0は3.11以上)。最新版をそろえるなら、Python 3.12以上で環境を作ってください。仮想環境の作り方はuvとは?Pythonの環境構築・パッケージ管理・バージョン管理の使い方を徹底解説が参考になります。
pip install "plotly[express]" pandas
# 版の確認
python -c "import plotly; print(plotly.__version__)" # 7.1.0
pip install plotlyの依存範囲とpxの追加要件
7.1.0のpip install plotlyで入る依存はnarwhalsとpackagingだけで、numpyもpandasも入りません。Python 3.12の空の仮想環境で順に試した結果は次のとおりです(ログは記事作成時に保存)。
| 入れたもの | 結果 |
|---|---|
| plotly のみ | import plotly.express で ImportError(numpyが必要) |
| plotly[express] | import は通るが px.data.iris() が ModuleNotFoundError |
| plotly[express] | px.bar(x=[…], y=[…]) が NotImplementedError |
| plotly[express] + pandas | 記事内のコードがすべて動く |
| plotly[express] + polars | pandasなしでも px.scatter が動く |
[express]で追加されるのはnumpyだけで、データフレームは別に入れる必要があります。公式手順も「supported dataframe library」を入れるよう書いていますが、具体名は挙げていません。迷ったらpandasを入れてください。リストを直接渡す書き方でもpandasが必要で、エラー文は「Pandas installation is required if no dataframe is provided.」です。データ処理にPolarsを使う場合は、px.data.iris(return_type="polars")のようにPolarsのデータフレームをそのまま渡せます。
JupyterLab・ノートブックの表示環境
JupyterLabでは、plotlyと同じ環境にjupyterlabとanywidgetを入れると、セルの末尾に置いたfigやfig.show()がその場に描画されます(公式Getting Started)。表示されずに空白になるときは、まずこの2つが同じ環境に入っているかを確認します。Jupyter自体の導入はJupyter Notebookのインストール手順|7.6系をpip・uv・condaで入れる方法を参照してください。
pip install jupyterlab anywidget
jupyter lab
plotly.expressによる基本グラフの作成
pxの関数には、データフレームと列名を渡します。colorに列名を渡せば色分け、sizeに渡せば点の大きさが自動で決まります。以下のPythonコードはPlotly 7.1.0でFigureの生成を確認しています。ただしfig.show()による画面表示は未検証です。
px.scatterによる散布図と色分け
付属のサンプルデータ(アヤメ150件)で、種類ごとに色を分けた散布図を作ります。hover_dataに列を足すと、ホバー時に表示される項目が増えます。
import plotly.express as px
df = px.data.iris()
fig = px.scatter(
df, x="sepal_width", y="sepal_length",
color="species", size="petal_length",
hover_data=["petal_width"],
)
fig.show()
color="species"で3系列(setosa・versicolor・virginica)に分かれ、凡例をクリックすると系列ごとに表示を切り替えられます。px.scatterは既定で、点が1,000を超えるとWebGLで描くscatterglトレースに切り替わります(7.1.0で1,000点はscatter、1,001点はscatterglになることを確認)。点数に関係なくWebGLで描きたいときはrender_mode="webgl"、ベクター形式で書き出したいときはrender_mode="svg"を指定します。
px.lineによる時系列の折れ線グラフ
時系列の推移はpx.lineです。markers=Trueで各データ点に印が付きます。日本の1人当たりGDPの推移(1952〜2007年の12時点)を描く例です。
import plotly.express as px
df = px.data.gapminder().query("country == 'Japan'")
fig = px.line(df, x="year", y="gdpPercap", markers=True)
fig.update_layout(xaxis_title="年", yaxis_title="1人当たりGDP(米ドル)")
fig.show()
pandasのデータフレームから直接描きたいときは、pd.options.plotting.backend = "plotly"を設定すると、df.plot()がMatplotlibではなくPlotlyのFigureを返します。ただし既定のMatplotlibバックエンドと完全互換ではなく、subplots=Trueなどの引数や、戻り値のAxesを操作するコードは書き換えが必要です(7.1.0でsubplots=TrueはTypeErrorになりました)。
graph_objectsによる二軸・複合グラフ
pxで組みにくいのは、左右に別の軸を持つ二軸グラフや、棒と折れ線のように種類の違うトレースを1枚に重ねる図です。このときは低レベルのplotly.graph_objects(go)で、add_traceでトレースを1本ずつ足します。
import plotly.graph_objects as go
fig = go.Figure()
fig.add_trace(go.Bar(x=["1月", "2月", "3月"], y=[120, 95, 140], name="売上"))
fig.add_trace(go.Scatter(x=["1月", "2月", "3月"], y=[0.12, 0.08, 0.15],
name="利益率", yaxis="y2", mode="lines+markers"))
fig.update_layout(
title="月次売上と利益率",
yaxis=dict(title="売上(万円)"),
yaxis2=dict(title="利益率", overlaying="y", side="right", tickformat=".0%"),
)
fig.show()
判断の基準は単純で、まずpxで書き、pxの引数で表現できない構成になったときだけgoに降ります。pxの戻り値もgoのFigureなので、pxで作った図にadd_traceでgoのトレースを足すこともできます。
px.timelineによるガントチャートの作成
工程表はpx.timelineで描きます。x_startとx_endに開始日と終了日の列、yにタスク名の列を渡します。
import pandas as pd
import plotly.express as px
tasks = pd.DataFrame([
dict(Task="要件定義", Start="2026-01-06", Finish="2026-01-17", Owner="企画"),
dict(Task="設計", Start="2026-01-20", Finish="2026-02-07", Owner="開発"),
dict(Task="実装", Start="2026-02-10", Finish="2026-03-13", Owner="開発"),
dict(Task="テスト", Start="2026-03-16", Finish="2026-03-27", Owner="QA"),
])
fig = px.timeline(tasks, x_start="Start", x_end="Finish", y="Task", color="Owner")
fig.update_yaxes(autorange="reversed") # Y軸を反転。この例では開始日の早いタスクが上に並ぶ
fig.show()
既定ではタスクが下から積まれるので、update_yaxes(autorange="reversed")で上から順に並べ替えるのが定番の調整です。x軸は日付軸になり、ホバーで開始日と終了日が出ます。
検索で上位に出る古い解説の多くはplotly.figure_factory.create_gantt()を使っていますが、この関数は7.0で削除されました。7.1.0で呼ぶとAttributeError: module 'plotly.figure_factory' has no attribute 'create_gantt'で止まります。古いコードを見つけたら、データフレームの列名をpx.timelineの引数に合わせて書き直してください。
Plotly 7で変わった点と古いコードの直し方
7.0.0(2026年8月25日)はメジャー更新で、6.x以前を前提にしたコードがそのままでは動かない変更が入りました。ネット上のサンプルの多くは6.x以前のものなので、エラーが出たら次の表に当てはまるかを先に見てください(CHANGELOGと7.1.0での実行結果)。
| 6.x以前の書き方 | 7.xでの結果 | 置き換え先 |
|---|---|---|
| ff.create_gantt | AttributeError | px.timeline |
| ff.create_distplot など | AttributeError | px.histogram(marginal)など |
| px.scatter_mapbox | 関数が無い | px.scatter_map |
| go.Scattermapbox | クラスが無い | go.Scattermap |
| write_image(engine=…) | TypeError | engine引数を外す |
| Orca・Kaleido 0.x | 非対応 | Kaleido 1.0以上 |
| rgba(0.5,0.2,0.1,1) | 色の解釈が変わる | 0〜255の整数で書く |
Figure Factoryで残っているのはcreate_dendrogram・create_quiver・create_tableなど7関数だけです。Mapbox系は、Plotly提供の地図スタイルではMapbox APIキーが不要なMapLibreベースの*_map関数に置き換わっており、7.1.0の同梱plotly.jsでは地図トレースにSafari 15・Chrome 56・Firefox 51以降が必要になりました。色の書式の変化は描画結果まで比べたPlotlyの色指定の解説で詳しく扱っています。
既存のプロジェクトで7.xへすぐ上げられない場合は、pip install "plotly<7"で6.9.0に留められます。ただし新しく書くコードは7.xの書き方に揃えておくほうが、後の移行で手戻りがありません。
Plotlyのグラフを共有する:HTML・Webアプリ・画像
Plotlyの図は、操作できる状態のままHTMLファイルとして渡せるのが強みです。ただし書き出し方でファイルサイズが大きく変わります。アヤメ150件の散布図で測った値です。
| 書き出し方 | サイズ | 向く場面 |
|---|---|---|
| write_html(既定) | 4,832,002バイト | オフラインで開く・メール添付 |
write_html(include_plotlyjs="cdn") |
16,338バイト | ネットにつながる環境での共有 |
| to_html(full_html=False) | div要素だけ | Django・Flaskのテンプレートに埋め込む |
既定の書き出しはplotly.js本体(約4.8MB)をファイルに丸ごと入れるため、ネット接続のない環境でも開けます。include_plotlyjs="cdn"にするとcdn.plot.ly/plotly-4.1.1.min.jsを読み込む形になり、ファイルは約300分の1になります。
import plotly.express as px
fig = px.scatter(
px.data.iris(), x="sepal_width", y="sepal_length",
color="species", size="petal_length",
hover_data=["petal_width"],
)
fig.write_html("iris.html") # 単体で開ける(約4.8MB)
fig.write_html("iris_cdn.html", include_plotlyjs="cdn") # CDN参照(約16KB)
# Django や Flask のテンプレートに渡す断片
div = fig.to_html(full_html=False, include_plotlyjs="cdn")
DjangoやFlaskで使うときは、to_html(full_html=False)が返す<div>から始まる断片をテンプレートに差し込みます。Djangoなら自動エスケープを避けるため|safeを付けて出力します。ボタンや入力欄と連動させたいならDash、PNGやPDFの静止画が要るならKaleido 1.0以上を入れてwrite_image()を使います。KaleidoはChromeまたはChromiumを使って描画するため、サーバーではブラウザの用意が必要です。
PlotlyとMatplotlib・Seaborn・Bokehの使い分け
Pythonの可視化ライブラリは、出力が「操作できるHTML」か「静的な画像」かで大きく分かれます。PyPIの直近30日のダウンロード数(pypistats、2026年10月27日取得)はplotlyが約4,878万回、matplotlibが約1億5,923万回です。ただしダウンロード数は利用者数ではないため、この差だけで利用の広がりは判断できません。
| ライブラリ | 最新版 | 出力 | 得意なこと |
|---|---|---|---|
| Plotly | 7.1.0 | HTML(操作可) | 探索・共有・Dashで画面化 |
| Matplotlib | 3.11.2 | PNG・PDF・SVG | 論文・資料の静的な図 |
| Seaborn | 0.13.2 | Matplotlibの図 | 統計グラフを短く書く |
| Bokeh | 3.10.1 | HTML(操作可) | サーバー連携・逐次更新 |
| Altair | 6.3.0 | HTML(Vega-Lite) | 宣言的な記法 |
結論から言うと、グラフを人に触ってもらう・Webに載せるならPlotly、紙やPDFに載せる図を細部まで整えるならMatplotlibです。Seabornは中身がMatplotlibなので、静的な統計グラフを短く書きたいときの選択肢です。BokehはPlotlyと同じくブラウザで動く図を作り、Bokehサーバーで値を逐次更新する用途に強みがあります。それぞれの詳細はMatplotlibとは?使い方・インストール・日本語化を3.11対応で解説、Seabornとは?pipインストールと使い方・Matplotlibとの違い【0.13.2対応】、Bokehとは?Pythonでインタラクティブなグラフを作る使い方【3.10対応】を参照してください。
Plotlyを選ぶべきでない場面
- 論文誌の投稿規定に合わせる図:フォントや線幅を細かく指定してPDFやEPSで出す作業は、Matplotlibのほうが資料も実例も多い。Plotly 7のKaleidoはEPS出力に対応していない。
- Chromeを置けないサーバーでのPNG一括生成:Kaleido 1.x はChromeまたはChromiumを前提にするため、ブラウザを入れられない環境ではMatplotlibで描くほうが早い。
- 数十万点を毎回HTMLで配る運用:データがHTMLにそのまま入るため、ファイルが重くなる。集計してから描くか、DashやBIツールで必要な範囲だけ返す構成にする。
グラフ単体ではなく、部署ごとに見る指標をまとめたダッシュボードを社内で運用したい段階になったら、Dashで作り込むか既製のBIツールを入れるかの判断になります。既製品を含めて検討する場合はBIツール導入支援の内容も参考にしてください。
よくある質問
Plotlyの読み方は?
「プロットリー」と読みます。ライブラリ名と、それを開発する会社名の両方に使われています。
Plotlyは無料で使えますか?
はい。plotly.py・plotly.js・DashはMITライセンスで、商用利用でも無料です。有料なのはDash Enterpriseなど、アプリを組織で配備・管理するための製品です。
pip install plotly をしたのに import plotly.express でエラーになるのはなぜですか?
7.xのpip install plotlyはnumpyとpandasを入れないためです。pip install "plotly[express]" pandasで入れ直すと動きます。Polarsのデータフレームを渡す場合はpandasなしでも動きます。ただしpx.data.iris()などのサンプルデータは既定でpandasを使うため、return_type="polars"を指定してください。
create_ganttが使えないときはどうすればいいですか?
create_ganttはPlotly 7.0で削除されました。px.timelineに開始日・終了日・タスク名の列を渡して書き直します。すぐに書き直せない場合だけ、6.9.0に版を固定する方法があります。
DjangoやFlaskでPlotlyのグラフを表示できますか?
できます。fig.to_html(full_html=False, include_plotlyjs="cdn")で得たdiv要素をテンプレートに埋め込みます。画面の操作とグラフを連動させたい場合はDashを使うほうが手数が少なくなります。