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

go(plotly.graph_objects) plotly

【Plotlyで散布図】go.Scatterglで大量のデータでグラフを作成する

2023年1月28日

今回はPythonのPlotlyで大量のデータを軽く扱うことができるgo.Scatterglの使い方とgo.Scatterとの比較を行う。1万以上のデータを散布図として扱う際はこの記事を参考にgo.Scatterglを活用してほしい。

もちろんgo.Scatterで1万のデータをグラフ化することも可能だが、グラフ作成時間やグラフ表示後の動きがカクカクして使いづらい。そんな時にWebGLを使用して動作するgo.Scatterglが活躍する。

本記事を通して1万や10万といった大量のデータを簡単に扱えるようになってほしい。

Python環境は以下。

  • Python 3.10.8
  • numpy 1.24.0
  • plotly 5.11.0
  • plotly-orca 3.4.2

参考になるサイト

Plotly公式

Qiita

Plotly Community Forum

本記事のコード全文

下準備のimport

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

まずは下準備としてのimport関連。今回はgoを使用する。pioplotlyでのグラフ保存用のライブラリ。保存の仕方は色々あるがpioはその1つだ。

また、本記事の最後にScatterScatterglの描画速度比較をするのでtimeimportしておく。

ScatterScatterglの違いと使い方

一般的に使われるgo.Scatterはsvg(ベクトル方式)を採用しており、グラフ化したりエクスポートした際に見やすくキレイな仕上がりになるのが特徴だ。また、一部の雑誌やWebサイトはこのsvgのみを公開している。

一方でgo.ScatterglはWebGL方式(ラスター方式)を採用しており、JavaScriptとGPUを使用して描画するので高速だ。GPUを使うことでCPUでは賄いきれない高処理負荷のグラフを描画可能。

ただしさらに一部のブラウザやPCではセキュリティの観点からWebGLが無効にされていたり学術論文では非推奨だ。

ということで私はgo.Scatterglを使うタイミングとしては以下の状況を考えている。

go.Scatterglを使うタイミングの目安

  • 10,000データを超えるグラフ
  • グラフの動きがモッサリしてきた
  • 見栄えより動作が重要

基本、大量のデータを扱わない限りは他のグラフと見た目上の差異がないgo.Scatterを使用するのが良いだろう。

Scatterglなら10万データをプロットしてもなめらか


ということで実際にgo.Scatterglを使用して10万データの散布図を作成してみた。ただ、このサイトに載せる際にデータ数が多すぎると表示できなかったので、サイト上ではデータ数を10,000に絞った。

実際にデータを触ってみるとわかるように、Scatterglを使うことで10,000データでも滑らかに動作させることが可能だ。

以下にScatterglで100,000データを描画し操作したときのgifを載せておく。

かなり滑らかに動作していることがわかるだろう。これだけ動かしているがデータ数は10万だ。

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

# 10万データをScatterglでプロットする

num = 100000
np.random.seed(1)
x = np.random.randn(num)
y = np.random.randn(num)

plot = [
    go.Scattergl(
        x=x, y=y, mode='markers',
        marker=dict(color=y, colorscale='jet'),
    )
]

layout =go.Layout(title='Scattergl')
fig = go.Figure(data=plot, layout=layout)
# グラフ全体とホバーのフォントサイズ変更
fig.update_layout(font_size=20, hoverlabel_font_size=20)
fig.show()

# グラフ保存
prefix = 'go-scattergl'  # 保存ファイル名の接頭辞
save_name = f"{prefix}_scattergl_{num}"
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")

Scatterだと動作がかなりもっさりする