カテゴリー

当サイトはアフィリエイトプログラムによる収益を得ています〈景品表示法に基づく表記です)

go

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

2021年4月5日

こんな人にオススメ

plotlyのとっかかりとして散布図(scatter)を描きたいけど、どうやって書けばいい?

ということで、今回はplotlygo.Scatterを使った散布図(scatter plot)の描き方について解説する。散布図は一番メジャーで基礎的なプロットの1つだから、本記事で理解していただけると幸いだ。

plotlyの基礎的な内容については以下の記事でも解説している。plotlyにはgo以外にもpxもあるので、興味があれば訪れてみてほしい。

【plotly&ボタン】plotlyのupdatemenusにbuttonsを追加

続きを見る

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

続きを見る

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

続きを見る

本記事はplotly公式の「Scatter Plots in Python」を参考にした。

python環境は以下

  • Python 3.10.1
  • numpy 1.21.4
  • pandas 1.3.5
  • plotly 5.4.0
  • plotly-orca 3.4.2

なお、新しく立ち上げたサイト「Pro天パ」ではリライト(書き直し)した記事を公開している。併せてご覧いただきたい。

運営者のメガネです。YouTubeTwitterInstagram、自己紹介はこちら、お問い合わせはこちらから。

運営者メガネ

作成したコード全文

下準備(import

import numpy as np
import pandas as pd
import plotly.graph_objects as go
import plotly.io as pio

まずは下準備としてのimport関連。今回は基本goを使用するが、一部データを作成・読み込みするためにnumpypandasを使用するのでimport

pioは以下の記事で解説している、plotlyでのグラフ保存用のライブラリ。保存の仕方は色々あるが、pioその1つだ。

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

続きを見る

シンプルにプロットする


まずはシンプルにプロットする。ここでは変数plotに格納するなど処理を細かく分解しているが、いきなりgo.Figurego.Scatterを入れてもいい。

散布図はgo.Scatterで描画可能。引数はx, yでそれぞれ横軸と縦軸の値に相当する。その他にも引数は多くあるが、最低限はこれだけあればグラフは描ける。

プロットデータはgo.Scatterの状態ではなく、listなどの配列に入れる必要がある。ここでは変数plotがその役割を果たす。プロットデータができるとそれをgo.Figureの引数dataに入れ、fig.showで表示。グラフの保存はhtml, png形式にしている。

import plotly.graph_objects as go
import plotly.io as pio

x = (0, 1, 2)
y = (1, 3, 2)

d = go.Scatter(
    x=x,  # xの値
    y=y,  # yの値
)
print(d)
# Scatter({
#     'x': [0, 1, 2], 'y': [1, 3, 2]
# })

# プロットはlistやtupleに入れないといけない
plot = [d]

# go.Figureでグラフ作成
fig = go.Figure(data=plot)  # plotは引数data
print(fig)
# Figure({
#     'data': [{'type': 'scatter', 'x': [0, 1, 2], 'y': [1, 3, 2]}], 'layout': {'template': '...'}
# })

# グラフの表示
fig.show()

# グラフ保存
prefix = 'go-scatter'  # グラフ保存時の接頭辞
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")

複数プロットは配列でまとめる

複数プロットをする場合は、プロットデータを配列の中に入れるといい。この例だと変数ploty0, y1のプロットデータを入れている。

あとはさっきと同じようにgo.Figureに格納したらいい。ここでは1データずつd0, d1として作成したが、もちろんfor文でループ作成してもいい。

import plotly.graph_objects as go
import plotly.io as pio

x = (0, 1, 2)
y0 = (1, 3, 2)
y1 = (2, 1, 3)

# 引数nameをプロットの名前をつけない場合は自動で「trace0」などの名称に
d0 = go.Scatter(
    x=x,  # xの値
    y=y0,  # y0の値
)

d1 = go.Scatter(
    x=x,  # xの値
    y=y1,  # y1の値
    name='y1'  # プロットの名前をy1に設定
)

# 複数プロットをまとまることも可能
plot = [d0, d1]

# go.Figureでグラフ作成
fig = go.Figure(data=plot)  # plotは引数data
print(fig)
# Figure({
#     'data': [{'type': 'scatter', 'x': [0, 1, 2], 'y': [1, 3, 2]},
#              {'name': 'y1', 'type': 'scatter', 'x': [0, 1, 2], 'y': [2, 1, 3]}],
#     'layout': {'template': '...'}
# })

fig.show()

# グラフ保存
prefix = 'go-scatter'
save_name = f"{prefix}_multiple"
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")

go.Layoutでレイアウトの設定

散布図に限った話ではないが、plotlyのグラフでタイトルや軸ラベルを追加したい時にはレイアウトの設定が必要。こちらも色々な方法があるが、ここではplotと同じように変数layoutで独立させる方法をとる。

このグラフだとグラフタイトルと横軸ラベルを追加した。それぞれgo.Layoutの引数titleの中のtext, 引数xaxistitleを使う。名前がtitletextなので注意。

layoutgo.Figureの中の引数layoutに入れると反映させることができる。

import plotly.graph_objects as go
import plotly.io as pio

x = (0, 1, 2)
y = (1, 3, 2)

plot = [go.Scatter(x=x, y=y)]

# レイアウトはgo.Layoutで設定可能
layout = go.Layout(
    title=dict(text='TITLE'),
    xaxis=dict(title='X'),
)
# レイアウトもgo.Figureに入れる
fig = go.Figure(data=plot, layout=layout)
fig.show()

# グラフ保存
prefix = 'go-scatter'
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")

modeでプロットの種類を変更


go.Scatterでは点だけや線と点など色々なパターンのプロットが可能。これらはgo.Scatterの引数modeで設定可能。modeでは以下の決まりがある。

  • ’lines’で線にする
  • ‘markers’で点にする
  • ‘text’でテキストにする
  • 上記をでつなげた組み合わせ
  • noenで非表示

今回のグラフでは合計8種類のグラフをyの値を変えながらプロットした。mode=’text’の際に表示するテキストは、go.Scatterの引数textで指定可能。ここではyの値にした。

また、noneにするとプロット点は非表示なるものの、マウスをかざすとちゃんとプロットされていることが確認できる。

import numpy as np
import plotly.graph_objects as go
import plotly.io as pio

# 引数modeでの組み合わせ
modes = [
    'lines', 'markers', 'text', 'none',
    'lines+markers', 'lines+text', 'markers+text',
    'lines+markers+text',
]

x = (0, 1, 2)
plot = []
for num, mode in enumerate(modes):  # forで全modeをプロット
    y = np.array((1, 3, 2)) + num  # 1プロットずつyの値を増やす
    d = go.Scatter(
        x=x, y=y,
        name=mode,  # プロットの名前はモードに
        mode=mode,  # プロットのモード
        text=y,  # modeにtextが入っている時用の表示テキストはyに
    )
    plot.append(d)

fig = go.Figure(data=plot)  # plotは引数data
fig.show()

# グラフ保存
prefix = 'go-scatter'
save_name = f"{prefix}_mode"
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")

textpositionでテキストの位置を変更

go.Scatterの引数textpositionを使用することで、テキストの表示位置を変更することができる。プロットする位置は各データ点の位置に変わりないが、その点の左上に置くのか右下に置くのかなどを指定できる。

今回の例だと一番プロット点がゴチャゴチャするだろうmode = 'lines+markers+text'を例として指定。選択可能なtextpositionは以下の合計9種類。

  • 'top left': 左上
  • 'top center': 真上
  • 'top right': 右上
  • 'middle left': 左
  • 'middle center': 中心
  • 'middle right': 右
  • 'bottom left': 左下
  • 'bottom center': 真下
  • 'bottom right': 右下

テキストがゴチャゴチャしやすいってときにはこのtextpositionを使用して位置調節するといいだろう。

import numpy as np
import plotly.graph_objects as go
import plotly.io as pio

x = (0, 1, 2)

# ごちゃごちゃするmode
mode = 'lines+markers+text'

# テキストを置く位置
textpositions = (
    'top left', 'top center', 'top right', 'middle left', 'middle center',
    'middle right', 'bottom left', 'bottom center', 'bottom right'
)

plot = []
for num, textposition in enumerate(textpositions):
    y = np.array((1, 3, 2)) + num
    d = go.Scatter(
        x=x, y=y,
        name=textposition,  # プロットの名前はtextpositionに
        mode=mode, text=textposition,
        textposition=textposition  # テキストを置く位置
    )
    plot.append(d)

fig = go.Figure(data=plot)  # plotは引数data
fig.show()

# グラフ保存
prefix = 'go-scatter'
save_name = f"{prefix}_textposition"
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")

バブルチャート作成

散布図は点のグラフなのでバブルチャートの作成も可能。バブルチャートでは点のサイズを変更する必要があるが、これはgo.Scattreの引数markerの中のsizeで可能。ここではさらに引数colorでマーカーの色も変更した。

バブルチャートについては以下の記事で応用的な内容で作成した。これらの記事ではスライダーを使用するなどより難しいグラフを作成した。

【plotly&バブルチャート】plotlyで各国の収入と平均寿命の時代変化をバブルチャートで描く

続きを見る

bubblechart2017_pop
【plotly&バブルチャート】plotlyで各国の収入と平均寿命をバブルチャートで描く

続きを見る

import plotly.graph_objects as go
import plotly.io as pio

fig = go.Figure(
    data=go.Scatter(
        x=[1, 2, 3, 4],
        y=[10, 11, 12, 13],
        mode='markers',
        marker=dict(
            size=[40, 60, 80, 100],  # マーカーのサイズ
            color=[0, 1, 2, 3]  # マーカーの色
        )
    )
)

fig.show()

# グラフ保存
prefix = 'go-scatter'
save_name = f"{prefix}_bubble"
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")

色々な色の設定方法

マーカーの色の指定は色々な方法がある。ここでは以下の4種類で作成。全て同じ色だが表現方法や不透明度が異なる。

  • CSSカラー: ‘violet'
  • HTMLカラー: ‘#ee82ee’
  • RGB: 'rgb(238, 130, 238)'
  • RGBa: 'rgba(238, 130, 238, 0.2)'

RGBaのaはalphaの略で、不透明度を表す。1だとくっきりハッキリだが、0だと完全に透明になる。デフォルトの色は不透明度1だが、ここでは最後のマーカーだけ不透明度を0.2にして少し薄くした。

また、以下のコードでmarker_sizeとしているが、これはマジックアンダースコア(Magic Underscore)と呼ばれるもので、marker=dict(size=...)と同じ意味になる。dictの中身が1つだけならこれで短く書ける。

import plotly.graph_objects as go
import plotly.io as pio

fig = go.Figure(
    data=go.Scatter(
        x=[1, 2, 3, 4],
        y=[10, 11, 12, 13],
        mode='markers',
        # マジックアンダースコアを使って書いてもいい
        marker_size=(0, 10, 50, 100),
        # 全てvioletカラー
        marker_color=(
            'violet',  # CSSカラー
            '#ee82ee',  # HTMLカラー
            'rgb(238, 130, 238)',  # rgb(Red, Green, Blue)
            'rgba(238, 130, 238, 0.2)'  # rgba(Red, Green, Blue, alpha)
        ),
    )
)

fig.show()

# グラフ保存
prefix = 'go-scatter'
save_name = f"{prefix}_bubble_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")

色をカラーバーで表現

マーカーの色を基準にカラーバーを追加することも可能。go.Scatter引数markerからcolor, colorscale, shoscaleを指定することで実現可能。colorscaleに関しては指定しなくてもデフォルトで色をつけてくれる。

一方で、colorを指定しないとplotly側がどの値を基準に色を決めたらいいのかわからないから、何もしてくれずに全プロットが同じ色で表示されるだけになる。

また、colorscaleはデフォルトではFalseなのでTrueにしないと表示されない。

import numpy as np
import plotly.graph_objects as go
import plotly.io as pio

np.random.seed(0)  # 乱数の固定
y = np.random.randn(500)
fig = go.Figure(
    data=go.Scatter(
        # xを省略するとデータのインデックスがxの値になる
        y=y,  # 500のランダムデータ作成
        mode='markers',
        marker=dict(
            size=16,
            color=y,  # マーカーの色をyにする
            colorscale='Viridis',  # カラースケール変更
            showscale=True  # カラーバーの表示
        )
    )
)
fig.show()

# グラフ保存
prefix = 'go-scatter'
save_name = f"{prefix}_colorbar"
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")

カラースケールの例

ここでカラースケールの一例を示しておく。その他のカラースケールや詳細については公式の「Built-in Continuous Color Scales in Python」参照。

今回は'Jet', 'Plotly3', 'Pinkyl', 'Picnic'の4種類で作成した。用途で使い分けるといいだろう。

import numpy as np
import plotly.graph_objects as go
import plotly.io as pio

np.random.seed(0)
y = np.random.randn(500)

# カラースケールの一例
colorscales = ('Jet', 'Plotly3', 'Pinkyl', 'Picnic')
for colorscale in colorscales:
    fig = go.Figure(
        data=go.Scatter(
            y=y,
            mode='markers',
            marker=dict(
                size=16, color=y,
                colorscale=colorscale,
                showscale=True
            )
        ),
        # グラフタイトルはtitle_textじゃなくてもいい
        layout=go.Layout(title=colorscale)
    )
    fig.show()

    # グラフ保存
    prefix = 'go-scatter'
    save_name = f"{prefix}_colorscale_{colorscale}"
    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")

symbolでマーカーのシンボルを変更


引数go.Scatterの引数markerの中のsymbolでマーカーのシンボルを変更可能。以下の記事やplotly公式の「Styling Markers in Python」で全てのシンボルについては記述されている。

シンボルは例外はあるが、塗りつぶし・白抜き・中心に点・白抜きと中心に点の4種類が存在している。ここではこれらを’circle’(円)に対して適用、その他メジャーなシンボルでグラフを作成した。

なお、わかりやすいようにマーカーのサイズはmarker_sizeで大きくした。

import numpy as np
import plotly.graph_objects as go
import plotly.io as pio

# シンボルの一例
symbols = (
    'circle', 'circle-open', 'circle-dot', 'circle-open-dot',
    'square', 'diamond', 'cross', 'triangle-up'
)

plot = []
for num, symbol in enumerate(symbols):
    y = np.array((1, 3, 2)) + num
    d = go.Scatter(
        x=x, y=y, name=symbol, mode='markers',
        marker_symbol=symbol,  # マーカーのシンボル
        marker_size=20,  # マーカーサイズ変更
    )
    plot.append(d)

fig = go.Figure(data=plot)
fig.show()

# グラフ保存
prefix = 'go-scatter'
save_name = f"{prefix}_symbol"
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")

dashで線の種類を変更


symbolは点の形状だったが、線の種類も引数dashで変更可能。dashの場合は引数は少なく、以下の6種類+1パターンのみ。

  • 'solid': 実線
  • 'dot': 点線
  • 'dash': 破線
  • 'longdash': 長い破線
  • 'dashdot': 一点鎖線
  • 'longdashdot': 長い破線の一点鎖線
  • '5px,10px,2px,2px': 5, 10, 2, 2 pixごとの破線

dashは引数lineの中のdashで変更可能。ここではマジックアンダースコアでつないで楽をした。

import numpy as np
import plotly.graph_objects as go
import plotly.io as pio

# 線種の一例
dashs = (
    'solid', 'dot', 'dash', 'longdash',
    'dashdot', 'longdashdot', '5px,10px,2px,2px'
)

plot = []
for num, dash in enumerate(dashs):
    y = np.array((1, 3, 2)) + num
    d = go.Scatter(
        x=x, y=y, name=dash,
        line_dash=dash,  # 線の種類
    )
    plot.append(d)

fig = go.Figure(data=plot)
fig.show()

# グラフ保存
prefix = 'go-scatter'
save_name = f"{prefix}_dash"
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")

update_tracesでプロットを後から編集

一度figを作成した後でも、追記や更新という形でfigを編集することが可能。ここでは先にfig自体を作成した後に、update_tracesでプロットデータを追記している。

以下の記事ではこのようにfig作成後のプロットデータの追記などを行う方法について解説している。

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

続きを見る

import numpy as np
import plotly.graph_objects as go
import plotly.io as pio

# 0-100までを100分割
t = np.linspace(0, 10, 100)
print(t)
# [ 0.          0.1010101   0.2020202   0.3030303   0.4040404   0.50505051
#   0.60606061  0.70707071  0.80808081  0.90909091  1.01010101  1.11111111
#   1.21212121  1.31313131  1.41414141  1.51515152  1.61616162  1.71717172
#   1.81818182  1.91919192  2.02020202  2.12121212  2.22222222  2.32323232
#   2.42424242  2.52525253  2.62626263  2.72727273  2.82828283  2.92929293
#   3.03030303  3.13131313  3.23232323  3.33333333  3.43434343  3.53535354
#   3.63636364  3.73737374  3.83838384  3.93939394  4.04040404  4.14141414
#   4.24242424  4.34343434  4.44444444  4.54545455  4.64646465  4.74747475
#   4.84848485  4.94949495  5.05050505  5.15151515  5.25252525  5.35353535
#   5.45454545  5.55555556  5.65656566  5.75757576  5.85858586  5.95959596
#   6.06060606  6.16161616  6.26262626  6.36363636  6.46464646  6.56565657
#   6.66666667  6.76767677  6.86868687  6.96969697  7.07070707  7.17171717
#   7.27272727  7.37373737  7.47474747  7.57575758  7.67676768  7.77777778
#   7.87878788  7.97979798  8.08080808  8.18181818  8.28282828  8.38383838
#   8.48484848  8.58585859  8.68686869  8.78787879  8.88888889  8.98989899
#   9.09090909  9.19191919  9.29292929  9.39393939  9.49494949  9.5959596
#   9.6969697   9.7979798   9.8989899  10.        ]

fig = go.Figure()

fig.add_trace(go.Scatter(
    x=t, y=np.sin(t),
    name='sin',
    mode='markers',
    marker_color='rgba(152, 0, 0, .8)'  # 不透明度0.8
))

fig.add_trace(go.Scatter(
    x=t, y=np.cos(t),
    name='cos',
    marker_color='rgba(255, 182, 193, .9)'  # 不透明度0.9
))

# 一括で変更したい場合はupdateで更新してもいい
fig.update_traces(
    mode='markers',  # 点だけに
    marker_line_width=2,  # マーカーの枠線の変更
    marker_size=10  # マーカーサイズ
)

fig.show()

# グラフ保存
prefix = 'go-scatter'
save_name = f"{prefix}_update_traces"
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のグラフの特徴でもあるホバー機能を編集するにはいくつかの方法がある。ここでは簡単な方法であるgo.Scatterの引数textを使用する方法について解説する。

引数textmodeに’text’が含まれているときに、プロットにテキストを表示するというものだった。しかし、公式の「Scatter Plots in Python」にあるように引数hoverinfoに’text’が含まれている、かつ、引数hovertextが指定されていないときは、引数textの内容がホバーに反映される。

Sets text elements associated with each (x,y) pair. If a single string, the same string appears over all the data points. If an array of string, the items are mapped in order to the this trace's (x,y) coordinates. If trace hoverinfo contains a "text" flag and "hovertext" is not set, these elements will be seen in the hover labels.

hoverinfoのデフォルト値は’all’でこれには’text’が含まれている。また、上のグラフでは引数hovertext(デフォルト値’’)を指定していないので、textで指定したState列のデータがホバーに反映される。

なお、x, yの値はデフォルトで表示されるので、textの内容はその下に表示される。ホバーの内容を自分でカスタムしたいなら、次で説明するhovertemplateを使うといい。

import pandas as pd
import plotly.graph_objects as go
import plotly.io as pio

file = '<https://raw.githubusercontent.com/plotly/datasets/master/2014_usa_states.csv>'
data = pd.read_csv(file)  # データの読み込み
print(data)
#     Rank                 State Postal  Population
# 0      1               Alabama     AL   4849377.0
# 1      2                Alaska     AK    736732.0
# 2      3               Arizona     AZ   6731484.0
# 3      4              Arkansas     AR   2966369.0
# 4      5            California     CA  38802500.0
# 5      6              Colorado     CO   5355866.0
# 6      7           Connecticut     CT   3596677.0
# 7      8              Delaware     DE    935614.0
# 8      9  District of Columbia     DC    658893.0
# 9     10               Florida     FL  19893297.0
# 10    11               Georgia     GA  10097343.0
# 11    12                Hawaii     HI   1419561.0
# 12    13                 Idaho     ID   1634464.0
# 13    14              Illinois     IL  12880580.0
# 14    15               Indiana     IN   6596855.0
# 15    16                  Iowa     IA   3107126.0
# 16    17                Kansas     KS   2904021.0
# 17    18              Kentucky     KY   4413457.0
# 18    19             Louisiana     LA   4649676.0
# 19    20                 Maine     ME   1330089.0
# 20    21              Maryland     MD   5976407.0
# 21    22         Massachusetts     MA   6745408.0
# 22    23              Michigan     MI   9909877.0
# 23    24             Minnesota     MN   5457173.0
# 24    25           Mississippi     MS   2994079.0
# 25    26              Missouri     MO   6063589.0
# 26    27               Montana     MT   1023579.0
# 27    28              Nebraska     NE   1881503.0
# 28    29                Nevada     NV   2839098.0
# 29    30         New Hampshire     NH   1326813.0
# 30    31            New Jersey     NJ   8938175.0
# 31    32            New Mexico     NM   2085572.0
# 32    33              New York     NY  19746227.0
# 33    34        North Carolina     NC   9943964.0
# 34    35          North Dakota     ND    739482.0
# 35    36                  Ohio     OH  11594163.0
# 36    37              Oklahoma     OK   3878051.0
# 37    38                Oregon     OR   3970239.0
# 38    39          Pennsylvania     PA  12787209.0
# 39    40           Puerto Rico     PR   3548397.0
# 40    41          Rhode Island     RI   1055173.0
# 41    42        South Carolina     SC   4832482.0
# 42    43          South Dakota     SD    853175.0
# 43    44             Tennessee     TN   6549352.0
# 44    45                 Texas     TX  26956958.0
# 45    46                  Utah     UT   2942902.0
# 46    47               Vermont     VT    626562.0
# 47    48              Virginia     VA   8326289.0
# 48    49            Washington     WA   7061530.0
# 49    50         West Virginia     WV   1850326.0
# 50    51             Wisconsin     WI   5757564.0
# 51    52               Wyoming     WY    584153.0

fig = go.Figure(
    data=go.Scatter(
        x=data['Postal'],
        y=data['Population'],
        mode='markers',
        marker_color=data['Population'],  # 色はPopulationに対応
        text=data['State']  # modeがtextでないときはホバーに反映
    )
)

# レイアウトにタイトルを追加
fig.update_layout(title='Population of USA States')
fig.show()

# グラフ保存
prefix = 'go-scatter'
save_name = f"{prefix}_hover"
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")

hovertemplateでホバーのスタイルを設定


引数hovertemplateを使用することで、自分好みのホバー内容にすることができる。hovertemplateでは「%」が使用でき、例えば%{x}とすることで各プロットのxの値をホバーに反映させられる。

また、marker_colorのようにdictで深くなっている引数の値の時はピリオド.を使用することで対処可能。

なお、改行は<br>、上付き文字は<sup>内容</sup>、下付き文字は<sub>内容</sub>とするなどタグを使用することでレイアウトの変更が可能。

import numpy as np
import pandas as pd
import plotly.graph_objects as go
import plotly.io as pio

file = '<https://raw.githubusercontent.com/plotly/datasets/master/2014_usa_states.csv>'
data = pd.read_csv(file)
print(data)
#     Rank                 State Postal  Population
# 0      1               Alabama     AL   4849377.0
# 1      2                Alaska     AK    736732.0
# 2      3               Arizona     AZ   6731484.0
# 3      4              Arkansas     AR   2966369.0
# 4      5            California     CA  38802500.0
# 5      6              Colorado     CO   5355866.0
# 6      7           Connecticut     CT   3596677.0
# 7      8              Delaware     DE    935614.0
# 8      9  District of Columbia     DC    658893.0
# 9     10               Florida     FL  19893297.0
# 10    11               Georgia     GA  10097343.0
# 11    12                Hawaii     HI   1419561.0
# 12    13                 Idaho     ID   1634464.0
# 13    14              Illinois     IL  12880580.0
# 14    15               Indiana     IN   6596855.0
# 15    16                  Iowa     IA   3107126.0
# 16    17                Kansas     KS   2904021.0
# 17    18              Kentucky     KY   4413457.0
# 18    19             Louisiana     LA   4649676.0
# 19    20                 Maine     ME   1330089.0
# 20    21              Maryland     MD   5976407.0
# 21    22         Massachusetts     MA   6745408.0
# 22    23              Michigan     MI   9909877.0
# 23    24             Minnesota     MN   5457173.0
# 24    25           Mississippi     MS   2994079.0
# 25    26              Missouri     MO   6063589.0
# 26    27               Montana     MT   1023579.0
# 27    28              Nebraska     NE   1881503.0
# 28    29                Nevada     NV   2839098.0
# 29    30         New Hampshire     NH   1326813.0
# 30    31            New Jersey     NJ   8938175.0
# 31    32            New Mexico     NM   2085572.0
# 32    33              New York     NY  19746227.0
# 33    34        North Carolina     NC   9943964.0
# 34    35          North Dakota     ND    739482.0
# 35    36                  Ohio     OH  11594163.0
# 36    37              Oklahoma     OK   3878051.0
# 37    38                Oregon     OR   3970239.0
# 38    39          Pennsylvania     PA  12787209.0
# 39    40           Puerto Rico     PR   3548397.0
# 40    41          Rhode Island     RI   1055173.0
# 41    42        South Carolina     SC   4832482.0
# 42    43          South Dakota     SD    853175.0
# 43    44             Tennessee     TN   6549352.0
# 44    45                 Texas     TX  26956958.0
# 45    46                  Utah     UT   2942902.0
# 46    47               Vermont     VT    626562.0
# 47    48              Virginia     VA   8326289.0
# 48    49            Washington     WA   7061530.0
# 49    50         West Virginia     WV   1850326.0
# 50    51             Wisconsin     WI   5757564.0
# 51    52               Wyoming     WY    584153.0

fig = go.Figure(
    data=go.Scatter(
        x=data['Postal'],
        y=data['Population'],
        mode='markers',
        marker_color=data['Population'],  # 色はPopulationに対応
        # ホバーのスタイルを設定
        hovertemplate=(
            # brタグで改行
            # %を使うとx, yの各値を指定可能
            'x = %{x}<br>'\\
            'y = %{y}<br>'\\
            # マジックアンダースコア(もしくはdict)を使う引数はピリオドで対応可能
            'color: %{marker.color}'\\
            # ホバー右の欄。extra内に何も書かないと表示がなくなる
            # bタグは太字、iタグは斜体
            '<extra><b>%{x}</b></extra>'
        )
    )
)

# レイアウトにタイトルを追加
fig.update_layout(title='Population of USA States')
fig.show()

# グラフ保存
prefix = 'go-scatter'
save_name = f"{prefix}_hovertemplate"
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")

customdataで好きなデータをホバーに置ける


引数customdataを使用することで、xy以外のデータもホバーに反映させることができる。ここではデータフレームdatacustomdataとして指定した。

そしてhovertemplateにてcustomdata[0]で0列目のRankcustomdata[1]で1 列目のStateを取り出した。

customdatalistnumpy配列、pandasのシリーズやここで使用したpandasのデータフレームなどに対応している。

import numpy as np
import plotly.graph_objects as go
import plotly.io as pio

file = '<https://raw.githubusercontent.com/plotly/datasets/master/2014_usa_states.csv>'
data = pd.read_csv(file)

fig = go.Figure(
    data=go.Scatter(
        x=data['Postal'], y=data['Population'], mode='markers',
        marker_color=data['Population'],
        customdata=data,  # データフレーム全体を使用してみる
        # 0番目がRank, 1番目がState
        hovertemplate='Rank: %{customdata[0]}, State: %{customdata[1]}'
    )
)

# レイアウトにタイトルを追加
fig.update_layout(title='customdata(set index number)')
fig.show()

# グラフ保存
prefix = 'go-scatter'
save_name = f"{prefix}_customdata"
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")

customdata.で名称での指定可能


0番目、1番目という指定だとややこしいって時には.を使ってそのまま名称指定する方法もある。ただし、そのためのデータを作成するのが少し面倒。

1データずつ、表示したい内容のdictを作成する必要がある。pandasのデータフレームの場合は.ilocを使用することで各行を取り出すことができるので、これをdictに変換したらいい。

customdata = []
for row in data.iloc:
    # 各行のデータをdictに変換して格納
    customdata.append(dict(row))

# 0行目のデータ
print(customdata[0])
# {'Rank': 1, 'State': 'Alabama', 'Postal': 'AL', 'Population': 4849377.0}

このdictが出来れば、あとはhovertemplatecustomdata.Rankのように名称指定が可能になる。

fig = go.Figure(
    data=go.Scatter(
        x=data['Postal'], y=data['Population'], mode='markers',
        marker_color=data['Population'],
        customdata=customdata,
        # 各データごとにdictでまとめていると、customdataを名称で指定可能
        hovertemplate='Rank: %{customdata.Rank}, State: %{customdata.State}'

    )
)

# レイアウトにタイトルを追加
fig.update_layout(title='customdata(set dict)')
fig.show()

# グラフ保存
prefix = 'go-scatter'
save_name = f"{prefix}_customdata_name "
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")

Scatterglで大量のデータも軽く扱える


最後にgo.Scatterglを使用した、大量データのプロット方法について解説する。詳しくは以下の記事で解説しているが、ざっくりいうとWebGLなるものを使って軽くするということ。

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

続きを見る

散布図の場合はgo.Scattreglを使用することで軽くグラフを作成することが可能になる。glなしの通常のgo.Scatterだと動かせないグラフになるくらい重くなる。

今回は1万データで乱数を作成しプロットした。なお、line_widthでマーカーの枠線の太さを1として枠線が見えるようにした。

import numpy as np
import plotly.graph_objects as go
import plotly.io as pio

# 1万データ作成
N = 10000
np.random.seed(1)
x = np.random.randn(N)
np.random.seed(2)
y = np.random.randn(N)

fig = go.Figure(
    # go.Scatterglで大データも軽く操作可能
    data=go.Scattergl(
        x=x, y=y, mode='markers',
        marker=dict(
            color=np.random.randn(N),
            colorscale='Viridis',
            line_width=1,  # マーカーの線の太さ
        )
    )
)

fig.show()

# グラフ保存
prefix = 'go-scatter'
save_name = f"{prefix}_scattergl"
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")

まずは散布図

ということで、今回はplotlygogo.Scatterを使って、散布図を作成した。他にも棒グラフや円グラフなど色々なグラフは存在するが、まずは散布図から。

plotlyの散布図では点だけじゃなくてテキストも線も使用可能なので、多くのグラフはこれで解決するだろう。

本記事がplotlyでグラフを書き始めるきっかけになれば幸いだ。

関連記事

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

続きを見る