カテゴリー

px

【plotly&3D】px.scatter_3dとpx.line_3Dで3Dグラフを作成

2021年11月6日

こんな人にオススメ

plotlypxで3Dグラフを描くのってどうしたらいい?

ということで、今回はplotlypxを使用して3Dグラフを作成する。以下の記事ではgoでの3Dグラフの描き方を解説している。

【plotly&3D】goで3Dグラフを作成

続きを見る

plotly公式の「3D Scatter Plots in Python3D Line Plots in Python」に3Dグラフの描き方の例が書かれているが、例が少なくてとっかかりにくい。また、

本記事ではもう少し踏み込んでグラフの描き方を解説するので、是非とも参考にしていただきたい。

python環境は以下。

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

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

運営者メガネ

作成したコード全文

下準備(import

import numpy as np
import pandas as pd
import plotly.express as px
import plotly.io as pio

まずは下準備としてのimport関連。今回はpxでの3Dグラフを扱うのでpximport。また、グラフ保存用にpioimportpioでのグラフ保存については以下。

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

続きを見る

あとはデータ作成のためにnumpypandasimportしている。

配列から3Dグラフを作成


まずは3種類の配列からグラフを作成する。以下のようにx, y, zを指定するとそのインデックスごとにプロットされる。例えば初めのプロットは0番目の(x, y, z) = (0, 0.5, 1)となる。

pxで3Dの散布図を作成するにはpx.scatter_3dを使う。2Dの散布図については以下。なお、初期のプロットは紫っぽい色の球状のマーカー(シンボル)となる。

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

続きを見る

また、単にグラフを作成しただけだとフォントサイズが小さめとの判断をしたので、fig.update_layoutでグラフ全体とホバーのフォントサイズを大きくしている。update_layoutなどに関しては以下。

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

続きを見る

import plotly.express as px
import plotly.io as pio

# 3つの配列でグラフを作成

x = (0, 0.5, 1, 0.5, 0)
y = (0.5, 1, 0, 0.5, 0)
z = (1, 0, 0.5, 0.5, 0)

fig = px.scatter_3d(x=x, y=y, z=z)
# グラフ全体とホバーのフォントサイズ変更
fig.update_layout(font_size=20, hoverlabel_font_size=20)
fig.show()

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

配列プロットの場合はcolor, symbolだけでは変わらない


続いては配列で作成した3Dグラフのマーカーと色を変更する。マーカー、色ともに引数symbol, colorで指定したらできるというわけではない。

これらの引数は後述する使用するデータフレームの列名に充てることが多い。そもそもpxのグラフはデータフレームありきでの使い方。

なので、配列からグラフを作成する際には以下の2ステップが必要。

  1. 引数colorsymbol)で色(マーカー)の区別方法を決める
  2. color_continuous_scalesymbol_sequence)で色の位置(マーカーの種類)を決める

要するに区別の仕方と種類を決める必要がある。以下の例では色は0から4で1プロットずつ変更、マーカーでは初め2つは同じマーカーにした。なので、マーカーは同じものが2つある。

注意点としては、色は自動でカラーバーになるということ。色を指定してもカラーバーに反映されるので、意図した色にしたいときは調節する必要がある。

なお、カラーバーと凡例は両立させると被ってしまうので、fig.update_layoutcoloraxisでカラーバーの長さを短くした。

import plotly.express as px
import plotly.io as pio

# プロットの色とシンボルを変更

x = (0, 0.5, 1, 0.5, 0)
y = (0.5, 1, 0, 0.5, 0)
z = (1, 0, 0.5, 0.5, 0)

# プロットの色
color_continuous_scale = ('red', 'blue', 'green', 'orange', 'pink')
# プロットのシンボル
symbol_sequence = ('circle', 'square', 'x', 'cross', 'diamond')

fig = px.scatter_3d(
    x=x, y=y, z=z,
    color=(0, 1, 2, 3, 4),  # カラーの区別を数値にする
    color_continuous_scale=color_continuous_scale,  # カラーバーに色をつける
    symbol=(0, 0, 1, 2, 3),  # シンボルの区別を数値にする
    symbol_sequence=symbol_sequence  # シンボルを変更する
)
# カラーバーの長さを短く
fig.update_layout(coloraxis=dict(colorbar=dict(len=0.5)))
# グラフ全体とホバーのフォントサイズ変更
fig.update_layout(font_size=20, hoverlabel_font_size=20)
fig.show()

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

color, symbolを指定しないと何も変わらない

検証のために引数colorsymbolをコメントアウトしてグラフを作成すると上のグラフになる。色もシンボルもデフォルトの状態になる。

import plotly.express as px
import plotly.io as pio

# color, symbolの指定をしないと反映されない

x = (0, 0.5, 1, 0.5, 0)
y = (0.5, 1, 0, 0.5, 0)
z = (1, 0, 0.5, 0.5, 0)

# プロットの色
color_continuous_scale = ('red', 'blue', 'green', 'orange', 'pink')
# プロットのシンボル
symbol_sequence = ('circle', 'square', 'x', 'cross', 'diamond')

fig = px.scatter_3d(
    x=x, y=y, z=z,
    # color=(0, 1, 2, 3, 4),  # カラーの区別を数値にする
    color_continuous_scale=color_continuous_scale,  # カラーバーに色をつける
    # symbol=(0, 0, 1, 2, 3),  # シンボルの区別を数値にする
    symbol_sequence=symbol_sequence  # シンボルを変更する
)
# カラーバーの長さを短く
fig.update_layout(coloraxis=dict(colorbar=dict(len=0.5)))
# グラフ全体とホバーのフォントサイズ変更
fig.update_layout(font_size=20, hoverlabel_font_size=20)
fig.show()

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

color, symbolだけだと区別はしてくれる

一方で、colorsymbolだけにすると区別はしてくれる。もちろん指定していないからデフォルトの色とシンボルになる。

import plotly.express as px
import plotly.io as pio

# color, symbolだけだと区別はしてくれる

x = (0, 0.5, 1, 0.5, 0)
y = (0.5, 1, 0, 0.5, 0)
z = (1, 0, 0.5, 0.5, 0)

fig = px.scatter_3d(
    x=x, y=y, z=z,
    color=(0, 1, 2, 3, 4),  # カラーの区別を数値にする
    # color_continuous_scale=color_continuous_scale,  # カラーバーに色をつける
    symbol=(0, 0, 1, 2, 3),  # シンボルの区別を数値にする
    # symbol_sequence=symbol_sequence  # シンボルを変更する
)
# カラーバーの長さを短く
fig.update_layout(coloraxis=dict(colorbar=dict(len=0.5)))
# グラフ全体とホバーのフォントサイズ変更
fig.update_layout(font_size=20, hoverlabel_font_size=20)
fig.show()

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

カラーバーの色をカラースケールに変更する


なお、カラーバーについてはカラースケールに対応させることも可能。カラースケールについてはplotly公式の「Built-in Continuous Color Scales in Python」に書かれている。

今回はJetなる色をチョイスし、引数color_continuous_scaleで適用させた。もちろん引数colorを指定しないと区別ができないからデフォルトの色になる。

import plotly.express as px
import plotly.io as pio

# カラーバーにカラースケールを設定

x = (0, 0.5, 1, 0.5, 0)
y = (0.5, 1, 0, 0.5, 0)
z = (1, 0, 0.5, 0.5, 0)

# 引数color, color_continuous_scale, color_discrete_sequenceでは無理
fig = px.scatter_3d(
    x=x, y=y, z=z,
    # color=(0, 1, 2, 3, 4),  # カラーの区別を数値にする
    color_continuous_scale='Jet',  # カラースケールを変更
)
# グラフ全体とホバーのフォントサイズ変更
fig.update_layout(font_size=20, hoverlabel_font_size=20)
fig.show()

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

データフレームからグラフを作成


pxは基本的にpandasのデータフレームを使用してグラフを描くことが多い。ここからはデータフレームを使用して解説する。

使用するデータフレームはpxirisのデータ。中身は以下。

import plotly.express as px
import plotly.io as pio

df = px.data.iris()
print(df)
#      sepal_length  sepal_width  ...    species  species_id
# 0             5.1          3.5  ...     setosa           1
# 1             4.9          3.0  ...     setosa           1
# 2             4.7          3.2  ...     setosa           1
# 3             4.6          3.1  ...     setosa           1
# 4             5.0          3.6  ...     setosa           1
# ..            ...          ...  ...        ...         ...
# 145           6.7          3.0  ...  virginica           3
# 146           6.3          2.5  ...  virginica           3
# 147           6.5          3.0  ...  virginica           3
# 148           6.2          3.4  ...  virginica           3
# 149           5.9          3.0  ...  virginica           3

# [150 rows x 6 columns]

# ヘッダ一覧
print(df.columns)
# Index(['sepal_length', 'sepal_width', 'petal_length', 'petal_width', 'species',
#        'species_id'],
#       dtype='object')

pxで3D散布図を作成するときはデータフレームとx, y, z情報を入れる。今回はxには’sepal_length’yには’sepal_width’、zには’petal_width’を指定。

単にプロットしただけなので、凡例もデータの色分けもない。色分けなどは次で解説する。

# データフレームから3Dグラフ作成
fig = px.scatter_3d(
    data_frame=df,  # 使用するデータフレーム
    x='sepal_length', y='sepal_width', z='petal_width',  # x, y, zの列名
)
fig.show()

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

データフレームのグラフで色やシンボルを変更

色の変更


色付けは上で見たように引数colorで行う。ただし、データフレームを使用しているので、指定するは色分けしたい列名(ヘッダ名)。

ここではspeciesで色分けするようにした。こうすると分布がわかりやすくなる。

import plotly.express as px
import plotly.io as pio

# データごとに色を変える
df = px.data.iris()
fig = px.scatter_3d(
    df, x='sepal_length', y='sepal_width', z='petal_width',
    color='species'  # speciesで色分け
)
fig.show()

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

シンボルの変更

シンボルの変更も引数symbolを使って簡単に行える。ただし、色が全て同じなのでわかりにくい。

import plotly.express as px
import plotly.io as pio

# データごとにシンボルを変える

df = px.data.iris()
fig = px.scatter_3d(
    df, x='sepal_length', y='sepal_width', z='petal_width',
    symbol='species'  # speciesでシンボル分け
)
# グラフ全体とホバーのフォントサイズ変更
fig.update_layout(font_size=20, hoverlabel_font_size=20)
fig.show()

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

色とシンボルの両方を変更


色とシンボルを変更するには引数colorsymbolを同時に指定したらいいだけ。今回は色はpetal_length、シンボルはspeciesで区別した。

色を数値データであるpetal_lengthにしたのでカラーバーが自動でついて調節される。ただし、長さを調節していないので、凡例と被ってしまっている。

import plotly.express as px
import plotly.io as pio

# データごとに色とシンボルを変える

df = px.data.iris()
print(df['petal_length'])
# 0      1.4
# 1      1.4
# 2      1.3
# 3      1.5
# 4      1.4
#       ...
# 145    5.2
# 146    5.0
# 147    5.2
# 148    5.4
# 149    5.1
# Name: petal_length, Length: 150, dtype: float64

fig = px.scatter_3d(
    df, x='sepal_length', y='sepal_width', z='petal_width',
    color='petal_length',  # petal_lengthで色分け
    symbol='species'  # speciesでシンボル分け
)
# グラフ全体とホバーのフォントサイズ変更
fig.update_layout(font_size=20, hoverlabel_font_size=20)
fig.show()

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

マーカーの最大サイズと不透明度をイジる


引数sizeでサイズの基準とするデータフレームの列名、size_maxでマーカーサイズの最大値、そしてopacityでマーカーの不透明度を設定することができる。

ここではpetal_lengthをサイズの基準として設定し、マーカーサイズの最大値は18、不透明度は0.5とした。

import plotly.express as px
import plotly.io as pio

# マーカーのサイズや不透明度を変更

df = px.data.iris()
fig = px.scatter_3d(
    df, x='sepal_length', y='sepal_width', z='petal_width',
    color='petal_length',  # petal_lengthで色分け
    symbol='species',  # speciesでシンボル分け
    size='petal_length',  # petal_lengthでマーカーのサイズ決め
    size_max=18,  # マーカーサイズの最大値を設定
    opacity=0.5  # 不透明度を変更
)
# グラフ全体とホバーのフォントサイズ変更
fig.update_layout(font_size=20, hoverlabel_font_size=20)
fig.show()

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

カラースケールを変更

カラースケールの変更はすでに行なったように引数color_continuous_scaleで変更可能。ここではcolor_continuous_scale=’Jet’で青から赤に変わるようにした。

import plotly.express as px
import plotly.io as pio

# カラースケールを変更

df = px.data.iris()

# color_continuous_scaleでカラースケールを変更
fig = px.scatter_3d(
    df, x='sepal_length', y='sepal_width', z='petal_width',
    color='petal_length',
    size='petal_length', symbol='species',
    color_continuous_scale='Jet',  # カラースケールを変更
)
# グラフ全体とホバーのフォントサイズ変更
fig.update_layout(font_size=20, hoverlabel_font_size=20)
fig.show()

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

fig.updateシリーズでグラフ内容を後から変更

fig.update_layoutでレイアウト関係を変更


すでに何回かコードを書いたが、fig.update_layoutを使うことで、figを作成した後にレイアウトの編集を行うことが可能。

ここではフォントサイズを20、カラーバーの長さを0.5に、余白を上下左右0に変更した。

import plotly.express as px
import plotly.io as pio

# fig.updateシリーズでfigに情報を追加する

# fig.update_layoutでレイアウトを編集
df = px.data.iris()
fig = px.scatter_3d(
    df, x='sepal_length', y='sepal_width', z='petal_width',
    color='petal_length',  # petal_lengthで色分け
    symbol='species',  # speciesでシンボル分け
    title='TITLE'  # グラフタイトルは引数にある
)
# グラフ全体とホバーのフォントサイズ変更
fig.update_layout(font_size=20, hoverlabel_font_size=20)
# カラーバーの長さを0.5に変更
fig.update_layout(coloraxis=dict(colorbar=dict(len=0.5)))
# 余白を削除する
fig.update_layout(margin=dict(l=0, r=0, b=0, t=0))
fig.show()

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

fig.update_tracesでプロット関係を変更


一方で、fig.update_tracesを使うことでプロット関係の変更をすることが可能。

ここではmarker=dict(size=20)でマーカーのサイズを20に固定した。px.scatter_3dの引数sizeはどのデータでサイズ分けするのかを決めるもので、marker=dict(size=20)sizeは単にマーカーのサイズを指定している。

なお、px.scatter_3dの引数titleでグラフタイトルをつけることができるのでつけておいた。fig.update_layoutでもいいが、元々引数にある。

import plotly.express as px
import plotly.io as pio

# fig.update_layoutでレイアウトを編集

df = px.data.iris()
fig = px.scatter_3d(
    df, x='sepal_length', y='sepal_width', z='petal_width',
    color='petal_length',  # petal_lengthで色分け
    symbol='species',  # speciesでシンボル分け
    title='TITLE'  # グラフタイトルは引数にある
)
# グラフ全体とホバーのフォントサイズ変更
fig.update_layout(font_size=20, hoverlabel_font_size=20)

# マーカーのサイズを20に変更
fig.update_traces(marker=dict(size=20))
fig.show()

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

カメラコントロールで視点変更

layoutの引数scene_cameraで視点変更可能


レイアウトの引数scene_cameraの引数eyeで視点変更可能。今回はx=0, y=2.5, z=0にしてx=’sepal_length’側から見たグラフを作成。

import plotly.express as px
import plotly.io as pio

# カメラ位置を変更

df = px.data.iris()
fig = px.scatter_3d(
    df, x='sepal_length', y='sepal_width', z='petal_width',
    color='petal_length',  # petal_lengthで色分け
    symbol='species',  # speciesでシンボル分け
)
# グラフ全体とホバーのフォントサイズ変更
fig.update_layout(font_size=20, hoverlabel_font_size=20)
# x=0, y=2.5, z=0で視点を変更
fig.update_layout(scene_camera=dict(eye=dict(x=0, y=2.5, z=0)))
fig.show()

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

視点を全て0にすると近すぎる


x=0, y=0, z=0の視点にしてしまうとあまりにも近すぎて見づらくなる。

import plotly.express as px
import plotly.io as pio

# 視点を全て0にすると近すぎる

df = px.data.iris()
fig = px.scatter_3d(
    df, x='sepal_length', y='sepal_width', z='petal_width',
    color='petal_length',  # petal_lengthで色分け
    symbol='species',  # speciesでシンボル分け
)
# グラフ全体とホバーのフォントサイズ変更
fig.update_layout(font_size=20, hoverlabel_font_size=20)
# x=0, y=0, z=0で視点を変更
fig.update_layout(scene_camera=dict(eye=dict(x=0, y=0, z=0)))
fig.show()

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

zをいい感じの値にしてあげると真上からのグラフになる。


# 真上から見るにはzをある程度の値にする

df = px.data.iris()
fig = px.scatter_3d(
    df, x='sepal_length', y='sepal_width', z='petal_width',
    color='petal_length',  # petal_lengthで色分け
    symbol='species',  # speciesでシンボル分け
)
# グラフ全体とホバーのフォントサイズ変更
fig.update_layout(font_size=20, hoverlabel_font_size=20)
# x=0, y=2.5, z=0で視点を変更
fig.update_layout(scene_camera=dict(eye=dict(x=0, y=0, z=3)))
fig.show()

# グラフ保存
prefix = 'px-scatter3d'  # 保存ファイル名の接頭辞
save_name = f"{prefix}_df_scene_camera_3"
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_3dline_3d

実はpx.scatter_3dだけじゃなくてpx.line_3dもある。px.line_3dは線のプロットがメイン。

同じデータをこれら2種類の方法で作成する。データは自作で以下。

import numpy as np
import pandas as pd
import plotly.express as px
import plotly.io as pio

t = np.linspace(0, 20, 100)
x, y, z = np.cos(t), np.sin(t), t
# プロットの名称を決めておく
name = ['+ 0'] * len(x) + ['+ 1'] * len(x) + ['+ 2'] * len(x)

# x, yはズラして作成、zは繰り返しで作成
x = np.hstack((x, x + 1, x + 2))
y = np.hstack((y, y + 1, y + 2))
z = np.tile(z, 3)

# dictにまとめてデータフレーム下
dct = {'x': x, 'y': y, 'z': z, 'name': name, }
# データフレームにまとめる
df = pd.DataFrame(dct)
print(df)
#             x         y          z name
# 0    1.000000  0.000000   0.000000  + 0
# 1    0.979663  0.200649   0.202020  + 0
# 2    0.919480  0.393137   0.404040  + 0
# 3    0.821898  0.569634   0.606061  + 0
# 4    0.690887  0.722963   0.808081  + 0
# ..        ...       ...        ...  ...
# 295  2.941964  2.335714  19.191919  + 2
# 296  2.855447  2.517891  19.393939  + 2
# 297  2.734136  2.679003  19.595960  + 2
# 298  2.582964  2.812498  19.797980  + 2
# 299  2.408082  2.912945  20.000000  + 2

# [300 rows x 4 columns]

x, yを1ずつずらしながら螺旋状になるようにデータを作成した。np.hstackは配列を縦にくっつけ、np.tileは同じ配列を繰り返すというもの。zは同じ間隔で直線に続けばいいのでnp.tileにした。

作成したx, y, zを名前とするnameを一度dictにしてからpandasデータフレームへと変換している。

px.scatter_3dで作成


まずはscatter_3dから。こちらは今までと同じように点でプロットされるだけ。色とマーカーはデータごとに分けておいた。

import numpy as np
import pandas as pd
import plotly.express as px
import plotly.io as pio

# scatter_3d

fig = px.scatter_3d(
    df, x='x', y='y', z='z',
    symbol='name',
    color='name',
)
# グラフ全体とホバーのフォントサイズ変更
fig.update_layout(font_size=20, hoverlabel_font_size=20)
fig.show()

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

px.line_3dで作成


続いてはline_3d。線がメインなので、symbolの代わりにline_dashが使われる。線の種類は次で確認するが、6種類しかない。まあ線の種類なんてそうそう多くない。

import numpy as np
import pandas as pd
import plotly.express as px
import plotly.io as pio

# line_3d

fig = px.line_3d(
    df, x='x', y='y', z='z',
    color='name',
    line_dash='name',
)
# グラフ全体とホバーのフォントサイズ変更
fig.update_layout(font_size=20, hoverlabel_font_size=20)
fig.show()

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

px.line_3dにマーカーを追加


最後にline_3dにマーカーを追加する。また、線の種類を確認するためにプロットの数は合計で9にした。データフレームの作成方法は先ほど同様、dictにしてからデータフレームへと落とし込む。

import numpy as np
import pandas as pd
import plotly.express as px
import plotly.io as pio

t = np.linspace(0, 20, 100)
x, y, z = np.cos(t), np.sin(t), t
# プロットの名称を決めておく
name = []
for num in range(9):
    string = [f"+ {num}"] * len(x)
    name.extend(string)

# x, yはズラして作成、zは繰り返しで作成
x = np.hstack((x, x + 1, x + 2, x + 3, x + 4, x + 5, x + 6, x + 7, x + 8))
y = np.hstack((y, y + 1, y + 2, y + 3, y + 4, y + 5, y + 6, y + 7, y + 8))
z = np.tile(z, 9)

# dictにまとめてデータフレーム下
dct = {'x': x, 'y': y, 'z': z, 'name': name, }
# データフレームにまとめる
df = pd.DataFrame(dct)
print(df)
#             x         y          z name
# 0    1.000000  0.000000   0.000000  + 0
# 1    0.979663  0.200649   0.202020  + 0
# 2    0.919480  0.393137   0.404040  + 0
# 3    0.821898  0.569634   0.606061  + 0
# 4    0.690887  0.722963   0.808081  + 0
# ..        ...       ...        ...  ...
# 295  2.941964  2.335714  19.191919  + 2
# 296  2.855447  2.517891  19.393939  + 2
# 297  2.734136  2.679003  19.595960  + 2
# 298  2.582964  2.812498  19.797980  + 2
# 299  2.408082  2.912945  20.000000  + 2

# [300 rows x 4 columns]

グラフを見ると線は実線、点線、破線、広めの破線、一点鎖線、広めの一点鎖線の繰り返しになっていることがわかるだろう。

fig = px.line_3d(
    df, x='x', y='y', z='z',
    color='name',
    line_dash='name',
)
# グラフの線の太さを太くする
fig.update_traces(line_width=5)
# グラフ全体とホバーのフォントサイズ変更
fig.update_layout(font_size=20, hoverlabel_font_size=20)
fig.show()

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

3Dはgoの方が簡単

今回はplotlypxを使用して3Dグラフを作成した。アニメーションやその他のグラフはpxの方がサクッと作成できて楽だったが、3Dに関してはgoの方が楽に描ける気がした。

データフレームに落とすもの大変だし色分けも引数がややこしくて面倒だった。ということで3Dに関してはgoでやることをおすすめする。

関連記事

【plotly&3D】goで3Dグラフを作成

続きを見る

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

続きを見る

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

続きを見る

【px&animation】plotly.expressでアニメーションのグラフを作成

続きを見る

【Plotly&animation】Plotlyのgoでアニメーションを作成

続きを見る

【px&バブルチャート】plotly.expressで各国の収入と平均寿命の時代変化をアニメーションで

続きを見る

ガジェット

2023/9/18

【デスクツアー2022下半期】モノは少なく、でも効率的に Desk Updating #0

今回はガジェットブロガーなのにデスク環境を構築していない執筆者の ...

ライフハック

2023/9/16

【Audible vs YouTube Premium】耳で聴く音声学習コンテンツを比較

ワイヤレスイヤホンが普及し耳で学習することへのハードルが格段に下 ...

完全ワイヤレスイヤホン(TWS)

2023/9/18

【SENNHEISER MOMENTUM True Wireless 3レビュー】全てが整ったイヤホン

今回は高音質・高機能なSENNHEISERのフラグシップ完全ワイヤレスイヤホン「SENNH ...

ライフハック

2023/3/11

【YouTube Premiumとは】メリットしかないから全員入れ

今回はYouTube Premiumを実際に使ってみてどうなのか、どんなメリット/デメリット ...

マウス

2023/8/17

【Logicool MX ERGOレビュー】疲れない作業効率重視トラックボールマウス

こんな人におすすめ トラックボールマウスの王道Logicool MX ERGOが気になるけどऩ ...

ベストバイ

2023/9/18

【ベストバイ2022】今年買って良かったモノのトップ10

2022年ベストバイ この1年を振り返って執筆者は何を買ったのか。ガジェッ& ...

スマホ

2023/1/15

【楽天モバイル×povo2.0の併用】月1,000円の保険付きデュアルSIM運用

こんな人におすすめ 楽天モバイルとpovo2.0のデュアルSIM運用って実際のとこ ...

マウス

2023/9/16

【Logicool MX ERGO vs MX Master 3】ERGOをメインにした決定的な理由

こんな疑問・お悩みを持っている人におすすめ 執筆者はLogicoolのハイエンӠ ...

macOSアプリケーション

2022/9/30

【Chrome拡張機能】便利で効率的に作業できるおすすめの拡張機能を18個紹介する

こんな人におすすめ Chromeの拡張機能を入れたいけど、調べても同じような ...

macOSアプリケーション

2023/5/3

【Automator活用術】Macで生産性を上げる作業の自動化術

今回はMacに標準でインストールされているアプリ「Automator」を使ってできる ...

Pythonを学びたいけど独学できる時間なんてない人へのすゝめ

執筆者は大学の研究室・大学院にて独学でPythonを習得した。

でも社会人になったら独学で行うには時間も体力もなくて大変だ。

時間がない社会人だからこそプロの教えを乞うのが効率的。

ここでは色んなタイプに合ったプログラミングスクールの紹介をする。

  • この記事を書いた人

メガネ

Webエンジニア駆け出し。独学のPythonで天文学系の大学院を修了。常時金欠のガジェット好きでM2 Pro MacBook Pro(30万円) x Galaxy S22 Ultra(17万円)使いの狂人。自己紹介と半生→変わって楽しいの繰り返しレビュー依頼など→お問い合わせ運営者情報、TwitterX@m_ten_pa、 YouTube@megatenpa、 Threads@megatenpa

-px
-, , ,