Plotlyの色(color)指定と使い方|Express・React・画像出力まで【v6対応】

Plotlyはブラウザ上で動くインタラクティブなグラフを、PythonでもJavaScriptでも同じ思想で描ける可視化ライブラリです。ただし2025年1月のv6で前提が大きく変わり、v5時代に書かれた解説どおりに進めると動かない箇所が出てきました。この記事では、2026年7月時点の最新版 plotly 6.9.0 で実際に動かして確認したPythonコードをもとに、多くの人がつまずく色(color)の指定を軸に、環境構築・APIの使い分け・画像出力・React連携までを整理します。

まとめ:Plotlyで最初に押さえる5点

  • 現行版:plotly 6.9.0(2026年7月9日リリース、plotly.js 3.7.0 同梱)。実行時依存は narwhals と packaging だけで、pandas は必須ではありません。
  • 色は3層で考える:カテゴリ=離散色(color_discrete_sequence / color_discrete_map)、数値=連続カラースケール(color_continuous_scale)、全体の既定色=テンプレートの colorway
  • APIの使い分け:手早く描くなら Plotly Express、細部を作り込むなら Graph Objects。ただし px が返すのも go.Figure なので併用できます。
  • 画像出力:Kaleido v1 系に変わり、Chrome を別途用意する必要があります。EPS は非対応です。
  • JavaScript側:plotly.js 3系・react-plotly.js 4系が現行。v2時代の transforms などは削除済みです。

以降で、それぞれを実行可能なコードとともに掘り下げます。

Plotly v6系の前提:インストールと、v5記事が古くなった点

まず環境です。インストールは pip で完結しますが、v6 からは用途に応じた extras(追加依存)が用意され、必要なものだけを足す形になりました。

# 本体(依存は narwhals と packaging のみ)
pip install plotly

# Plotly Express を使う(numpy が入る)
pip install "plotly[express]"

# PNG・SVG・PDF を書き出す(kaleido が入る)
pip install "plotly[kaleido]"

# 本記事のサンプルは px.data の組み込みデータを使うため pandas も必要
pip install pandas

PyPI の依存定義を見ると、plotly 6.9.0 本体が要求するのは narwhals>=1.15.1packaging だけです。v5 までの「Plotly を使うならまず pandas」という前提はすでに正しくありません。v6 の Plotly Express は Narwhals 経由でデータフレームを扱うため、pandas でも Polars でも PyArrow でも同じ書き方で描画できます。ただし px.data.gapminder() のような組み込みデータセットは既定で pandas のデータフレームを返す仕様のため、本記事のサンプルを動かす場合は pandas を入れてください(ライブラリの依存としては不要でも、サンプルデータの取得には必要です)。

v5時代の解説をそのまま真似すると詰まる箇所

ネット上に残る手順の多くは v5 前提のままです。とくに次の3点は現行版では不要、あるいは動きません。第一に、Jupyter Notebook 6以下のサポートは v6.0.0 で終了しており、最低要件は Notebook 7.0.0 です。v5 の記事にある jupyter nbextension enable のような有効化作業や、plotly==5.18.0 のようなバージョン固定はもう必要ありません。第二に、グラフの読み込みは requirejs からネイティブのES6 importへ移行し、go.FigureWidget は anywidget ベースになりました。第三に、画像出力の orca は役目を終え、後述する Kaleido v1 系に一本化されています。

Plotlyの色(color)指定を体系で覚える

Plotlyでもっとも質問が多いのが色です。個別の関数名を丸暗記すると混乱しますが、「何に色を割り当てるのか」で3層に分けると一気に整理できます。カテゴリ(国名・製品名など質的データ)に色を割り当てるなら離散色、数値(売上・人口など量的データ)に色を割り当てるなら連続カラースケール、そして何も指定しないときの既定色はテンプレートの colorway が決めています。以下、この3層に「一覧の確認」「後から変更」を加えて順に見ます。

カテゴリを色分けする(離散色:color_discrete_sequence / color_discrete_map)

Plotly Express では color にカテゴリ列を渡すと自動で色分けされます。色そのものを指定したいときは、順番で当てるなら color_discrete_sequence、値ごとに固定するなら color_discrete_map を使います。ブランドカラーを特定カテゴリに必ず当てたい、といった実務要件は後者で満たせます。

import plotly.express as px

df = px.data.gapminder().query("year == 2007")

fig = px.scatter(
    df, x="gdpPercap", y="lifeExp", color="continent",
    color_discrete_sequence=px.colors.qualitative.G10,   # 順番に割り当てる
    color_discrete_map={"Asia": "#EF553B", "Europe": "#636EFA"},  # 値を固定
)
fig.show()

両方を指定した場合、color_discrete_map に書いた値が優先されます。ここで注意したいのが、残りのカテゴリに color_discrete_sequence の色が先頭から詰めて割り当てられるわけではない点です。マップで固定したカテゴリもシーケンスのインデックスを消費するため、上の例では G10 の先頭2色(#3366CC・#DC3912)は使われず、3番目以降の色が残りのカテゴリに当たります。配色を厳密に決めたいなら、シーケンスに頼らず全カテゴリを color_discrete_map で書き切るのが安全です。なお、データ列そのものに CSS カラー名や16進カラーが入っている場合は color_discrete_map="identity" と書くと、その値をそのまま色として使えます。

数値に応じて色を変える(連続カラースケールとカラーバー)

数値列を color に渡すと、Plotly は自動的に連続カラースケールに切り替え、右側にカラーバーを表示します。スケールの種類は color_continuous_scale、色が張られる数値範囲は range_color、中央値を基準に色を分けたいときは color_continuous_midpoint で制御します。

import plotly.express as px

df = px.data.gapminder().query("year == 2007")

fig = px.bar(
    df.head(5), x="country", y="pop", color="pop",
    color_continuous_scale="Viridis",   # px.colors.sequential.Viridis でも可
    range_color=[0, 50_000_000],        # 色を張る数値範囲を固定
)
fig.update_layout(coloraxis_colorbar_title="人口")
fig.show()

range_color を固定すると、複数のグラフを並べたときに同じ数値が同じ色になり、比較できる図になります。逆に指定しないとグラフごとにスケールが伸縮するため、色が示す意味がグラフ間でずれます。指定する範囲はデータの実レンジに合わせてください。上の5か国の人口は最大でも約4,030万人なので、たとえば範囲を10億に取ると全ての棒がスケール下端の同系色に潰れ、色で差が読めない図になります。カラーバーの見出しは coloraxis_colorbar_title、位置や長さは coloraxis_colorbar 配下の属性で調整します。

主要なパレットとカラースケールの一覧

Plotlyが標準で持つ配色は、カテゴリ用(qualitative)・連続用(sequential)・発散用(diverging)の3グループに分かれています。よく使うものを、実際に plotly 6.9.0 から取得した色数とあわせて示します。

グループ 名前 色数 用途
qualitative Plotly(既定) 10 一般的なカテゴリ色分け
qualitative D3 / G10 / T10 各10 他ツールと配色を揃えたいとき
qualitative Set1 / Set2 / Set3 9 / 8 / 12 ColorBrewer系の定番
qualitative Pastel / Bold / Vivid / Safe 各11 Safeは色覚多様性に配慮
qualitative Dark24 / Light24 / Alphabet 24 / 24 / 26 カテゴリが多いとき
sequential Viridis / Plasma / Cividis 各10 大小が読める順序尺度
sequential Blues / Turbo 9 / 15 単色濃淡・広い色域
diverging RdBu / Picnic 各11 基準値からの正負を表す

カテゴリ数がパレットの色数を超えると色は循環して重複するため、系列数に合うパレットを選ぶことが重要です(10系列を超えるなら Dark24 や Alphabet)。既定パレット Plotly の10色は #636EFA#EF553B#00CC96#AB63FA#FFA15A#19D3F3#FF6692#B6E880#FF97FF#FECB52 で、Plotlyの見慣れた青・赤・緑…の正体がこれです。

色見本を自分で描いて確認する

一覧を目で確かめたいときは、色見本を自分で描かせるのが確実です。px.colors のグループ別モジュールには swatches() という関数があり、パレット一覧を Figure として返します。カラースケール名は文字列でも渡せる(例:"Viridis")ので、色見本で名前を見つけて文字列指定するのが実務では手早い方法です。

import plotly.express as px

px.colors.qualitative.swatches().show()   # カテゴリ用パレット一覧
px.colors.sequential.swatches().show()    # 連続カラースケール一覧
px.colors.diverging.swatches().show()     # 発散型カラースケール一覧

print(px.colors.qualitative.Plotly)
# ['#636EFA', '#EF553B', '#00CC96', '#AB63FA', '#FFA15A',
#  '#19D3F3', '#FF6692', '#B6E880', '#FF97FF', '#FECB52']

既存グラフの色を後から変える・Graph Objectsで直接指定する

すでに作った Figure の色だけ差し替えたい場合は、作り直さずに update_traces() で上書きできます。selector を使うと、特定の系列だけを狙って変更できます。

import plotly.express as px
import plotly.graph_objects as go

fig = px.line(px.data.stocks(), x="date", y=["GOOG", "AAPL"])
fig.update_traces(line_color="#D62728", selector=dict(name="AAPL"))  # AAPLの線だけ赤に

# Graph Objects なら要素ごとに色を直接渡せる
bar = go.Figure(go.Bar(x=["A", "B"], y=[3, 5], marker_color=["#636EFA", "#EF553B"]))
bar.update_layout(template="plotly_white")
bar.show()

Graph Objects では marker_color にリストを渡すと棒ごとに色を変えられ、線グラフなら line_color、縁取りは marker_line_colormarker_line_width で指定します。Plotly Express で骨格を作り、細部だけ update_traces() で詰めるのが、コード量と自由度のバランスが良い進め方です。

サイト全体の配色をテンプレート(colorway)で統一する

グラフごとに色を指定して回ると、レポート全体で配色がばらつきます。既定色はテンプレートの layout.colorway が持っているので、自社の配色を1回テンプレートとして登録し、既定テンプレートに設定するのが確実です。

import plotly.io as pio

pio.templates["corp"] = dict(
    layout=dict(colorway=["#0F62FE", "#FF832B", "#24A148", "#8A3FFC"])
)
pio.templates.default = "plotly_white+corp"   # 既存テンプレートと合成できる

テンプレートは + で合成できるため、白背景の plotly_white に自社の配色だけを重ねる、といった使い方ができます。なお v6.8.0 では、テンプレート側が autocolorscale=True のときに color_continuous_scale の指定が無視される不具合が修正されています。連続色が効かないと感じたら、まず plotly のバージョンを上げてください。

Plotly Express と Graph Objects の使い分け

2つのAPIは対立するものではありません。px.scatter() などが返す値は plotly.graph_objects.Figure そのものなので、px で作った Figure に対して、そのまま Graph Objects のトレースを追加できます

import plotly.express as px
import plotly.graph_objects as go

df = px.data.gapminder().query("year == 2007")

fig = px.scatter(df, x="gdpPercap", y="lifeExp", color="continent")
fig.add_trace(go.Scatter(x=[40000], y=[82], mode="markers+text",
                         text=["目標水準"], marker_color="black"))
fig.update_layout(title="1人あたりGDPと平均寿命")

判断基準はシンプルです。データフレームの列を軸・色・大きさに割り当てるだけで表せる図なら Plotly Express、複数のグラフ種を1枚に重ねる・軸を個別制御するなど「1関数では表せない図」なら Graph Objects で組み立てます。実務では px で骨格を作り、残りを add_trace()update_layout() で補うのが定石です。なお同じPythonの可視化でも、統計的な分布表現を素早く描きたいなら PythonのSeabornとは?使い方・グラフの種類・インストールを解説【2026年最新】のほうが記述量は少なく済みます。Plotlyはブラウザ上の操作性が要るときに選ぶ、と住み分けると迷いません。

レイアウト・軸・日本語表示を整える(update_layout)

タイトル、軸ラベル、フォント、余白といった見た目は update_layout() に集約されています。軸まわりは update_xaxes() / update_yaxes() でも同じ設定に届きます。

fig.update_layout(
    title="月次売上の推移",
    font=dict(family="Noto Sans JP, sans-serif", size=14),
    margin=dict(l=40, r=20, t=60, b=40),
    width=900, height=450,
    legend=dict(orientation="h", y=1.05, x=0),
)
fig.update_yaxes(tickformat=",", ticksuffix=" 円", rangemode="tozero")

日本語表示について、よくある誤解を1つ整理します。ブラウザに描画する限り、日本語が文字化けすることは基本的にありません。Plotlyのグラフは閲覧側のブラウザがフォントを解決するため、日本語フォントが入った環境ならそのまま表示されます。font.family の指定は「文字化けを直すため」ではなく、CSSと同じくフォントの見た目を揃えるためのものです。文字が豆腐(□)になるのは、次章の静的画像書き出しで、書き出しに使う Chrome 側に日本語フォントが無い場合がほとんどです。この点は、実行環境のフォント設定が描画結果を左右する Matplotlibとは?Pythonでグラフを描く使い方を入門から実践まで解説とは事情が異なります。

PNG・SVG・PDF・HTMLへの書き出し(Kaleido v1)

静的画像の書き出しは v6 系で仕組みが変わりました。Kaleido v1 は Chrome を同梱せず、マシンにある Chrome / Chromium を探して使います。そのため、サーバーやCIコンテナのようにブラウザが入っていない環境では、明示的に取得する必要があります。

pip install "plotly[kaleido]"
plotly_get_chrome          # コマンドラインから Chrome を取得

Python から実行するなら import plotly.io as pio のうえで pio.get_chrome() を呼びます。Chrome の場所を自分で指定したい場合は環境変数 BROWSER_PATH で上書きできます。準備ができたら、書き出しは拡張子で形式が決まります。

fig.write_image("chart.png")   # PNG
fig.write_image("chart.svg")   # SVG
fig.write_image("chart.pdf")   # PDF

fig.write_html("chart.html", include_plotlyjs="cdn")  # 操作可能なHTML

形式選択の注意点として、EPS は Kaleido v1 では扱えません(v1未満が poppler 併用で対応していました)。印刷・入稿用途ならベクターは PDF か SVG を選びます。また write_html()include_plotlyjs は出力サイズを大きく左右します。単純な棒グラフを plotly 6.9.0 で書き出して比べると、"cdn" 指定では 7.9KB、既定(plotly.js を丸ごと埋め込む)では 4,745KB になりました。Webに置くなら CDN 参照、オフラインで配布するなら既定のまま、と使い分けてください。書き出した図をそのままWebアプリに載せたいなら、Streamlitとは?メリット・デメリットと他フレームワーク比較・料金を解説で紹介しているフレームワークに Figure を渡すのが最短です。

JavaScript・Reactで使う(plotly.js 3系 / react-plotly.js 4系)

Plotlyの本体は JavaScript ライブラリ plotly.js で、Python版はそのラッパーです。npm 上の現行版は plotly.js 3.7.0、Reactラッパーの react-plotly.js は 4.0.0 で、peer dependency として plotly.js 3.0.0 以上と React 18 または 19 を要求します。

npm install plotly.js react-plotly.js
import Plot from "react-plotly.js";

export default function Chart() {
  return (
    <Plot
      data={[{ type: "bar", x: ["A", "B"], y: [3, 5],
               marker: { color: ["#636EFA", "#EF553B"] } }]}
      layout={{ title: "売上", colorway: ["#0F62FE", "#FF832B"] }}
      config={{ responsive: true }}
    />
  );
}

色の考え方はPython版と共通で、トレース単位なら marker.color、図全体の既定色なら layout.colorway です。ただし plotly.js 3.0.0 では非推奨だった属性がまとめて削除されました。transforms(フィルタ・グループ化)、titlefont 系、bardirannotation.refautotick、そして pointcloudheatmapgl トレースが対象です。v2 時代のサンプルを貼って動かない場合は、まずこれらを疑ってください。地図系については Mapbox ベースのトレースが非推奨となり、MapLibre ベース(scatter_map など)へ移行しています。Pythonだけで対話的なダッシュボードまで作りたい場合は、Plotly と同じ開発元が提供する Python DASHとは?その特徴と主な用途のフレームワークが選択肢になります。

v5からv6へ移行するときのチェックリスト

古いコードや古い記事の手順を持ち込んだときに、実際にエラーや無反応になりやすい箇所を整理します。

v5までの前提 v6系での扱い
Notebook 6以下 + nbextension有効化 Notebook 7.0.0以上(有効化は不要)
pandas が事実上の必須依存 依存は narwhals と packaging のみ
orca で画像書き出し Kaleido v1(Chromeを別途用意)
EPS で書き出し 非対応。PDF または SVG
transforms でフィルタ・集約 plotly.js 3.0.0 で削除
titlefont / bardir / autotick 削除。font / orientation へ置換
scatter_mapbox 等のMapbox系 非推奨。scatter_map 等のMapLibre系へ

移行時にもっとも影響が大きいのは transforms の削除です。plotly.js 側でフィルタリングやグループ化を宣言していた図は、データ側であらかじめ絞り込んでからトレースを組み立てる形に書き換える必要があります。Python版で px を使っていれば、この処理は元々データフレーム側で完結しているため影響を受けません。データフレームの行・列を絞る操作そのものに不慣れなら、ilocの使い方|pandasで行・列を抽出、locとの違いも解説で前処理側を押さえておくと移行が楽になります。

よくある質問

Plotlyの色を指定しても反映されないのはなぜですか?

指定した色の種類とデータ型が食い違っているケースが大半です。カテゴリ列に対して color_continuous_scale を指定しても効かず、逆に数値列へ color_discrete_sequence を渡しても無視されます。数値を「区分」として色分けしたいなら、その列を文字列型に変換してから color に渡してください。加えて、テンプレート側が autocolorscale=True のときに color_continuous_scale が無視される不具合が v6.8.0 で修正されているため、古い 6.x を使っているならバージョン更新も試す価値があります。

Plotly Express と Graph Objects はどちらを覚えるべきですか?

先に Plotly Express です。px が返すのも go.Figure なので、Express で描いた図に対して add_trace()update_traces() で Graph Objects の機能を後から足せます。最初から go だけで組むと記述量が跳ね上がるため、「px で描く → 足りない部分だけ go で補う」が効率的です。

PlotlyでPythonのグラフを画像として保存できないときは?

Kaleido v1 は Chrome を同梱しないため、ブラウザが無い環境では fig.write_image() が失敗します。pip install "plotly[kaleido]" の後に plotly_get_chrome(または pio.get_chrome())を実行してください。書き出した画像で日本語が豆腐になる場合は、Plotly側ではなく書き出しに使う Chrome の実行環境に日本語フォントが入っていないことが原因です。

Plotlyは商用利用できますか?

plotly.py と plotly.js はいずれも MIT ライセンスで公開されており、商用製品への組み込みを含めて利用できます。有償なのは Dash Enterprise などの商用サポート製品であり、ライブラリ本体の利用に費用はかかりません。

PlotlyとMatplotlibはどう使い分けますか?

ブラウザ上でのホバー表示・ズーム・凡例クリックによる系列の出し分けなど、読者が操作する図なら Plotly です。論文やPDF資料に貼る静的な図、細かい描画制御を効かせたい図なら Matplotlib が扱いやすく、資産も豊富です。Plotly も write_image() で静止画にできるため、「まず Plotly で作り、必要に応じて画像化する」進め方も現実的です。

関連記事

資料請求

RELATED POSTS 関連記事