はじめに
Matplotlibライブラリを利用して3D棒グラフを作図します。
3D棒グラフの作成
Matplotlib
ライブラリのPyPlot
モジュールのbar3d()
を使って3次元の棒グラフを作成します。
利用するライブラリを読み込みます。
# 利用するライブラリ import numpy as np import matplotlib.pyplot as plt
基本形の確認
まずは、デフォルトの設定で3D棒グラフを作成します。
プロットする点の値を設定します。
# 起点を指定 x = 0.0 y = 0.0 z = 0.0 # 変化量を指定 dx = 1.0 dy = 1.0 dz = 1.0
3次元の空間上の点$(x, y, z)$を指定します。
また、指定した点からの幅dx
、奥行きdy
、高さdz
を指定します。
Axes.bar3d()
で3D棒グラフを作成します。
# 3D棒グラフを作成 fig = plt.figure(figsize=(9, 8)) # 図の設定 ax = fig.add_subplot(projection='3d') # 3D用の設定 ax.bar3d(x=x, y=y, z=z, dx=dx, dy=dy, dz=dz) # 3D棒グラフ ax.set_xlabel('x') # x軸ラベル ax.set_ylabel('y') # y軸ラベル ax.set_zlabel('z') # z軸ラベル ax.set_title('bar3d', fontsize='20') # タイトル plt.show() # 描画
これが基本形のグラフです。
補助線を引いて、各引数の影響を確認します。
・作図コード(クリックで展開)
# 3D棒グラフを作成 fig = plt.figure(figsize=(9, 8)) # 図の設定 ax = fig.add_subplot(projection='3d') # 3D用の設定 ax.bar3d(x=x, y=y, z=z, dx=dx, dy=dy, dz=dz, color='white', alpha=0.25) # 3D棒グラフ ax.scatter(xs=x, ys=y, zs=z, s=100, color='purple', label='(x, y, z)') # 起点 ax.scatter(xs=x+dx, ys=y, zs=z, s=100, color='red', label='(x+dx, y, z)') # x軸方向に変化した点 ax.scatter(xs=x, ys=y+dy, zs=z, s=100, color='pink', label='(x, y+dy, z)') # y軸方向に変化した点 ax.scatter(xs=x, ys=y, zs=z+dz, s=100, color='orange', label='(x, y, z+dz)') # z軸方向に変化した点 ax.scatter(xs=x+dx, ys=y+dy, zs=z+dz, s=100, color='springgreen', label='(x+dx, y+dy, z+dz)') # 全ての軸で変化した点 ax.quiver(x, y, z, dx, 0.0, 0.0, color='purple', linestyle='--', arrow_length_ratio=0.1) # x軸の変化量 ax.quiver(x, y, z, 0.0, dy, 0.0, color='purple', linestyle='--', arrow_length_ratio=0.1) # y軸の変化量 ax.quiver(x, y, z, 0.0, 0.0, dz, color='purple', linestyle='--', arrow_length_ratio=0.1) # z軸の変化量 ax.quiver(x, y, z, dx, dy, dz, color='purple', arrow_length_ratio=0.1) # 全ての軸の変化量 ax.set_xlabel('x') # x軸ラベル ax.set_ylabel('y') # y軸ラベル ax.set_zlabel('z') # z軸ラベル ax.set_title('bar3d', fontsize='20') # タイトル fig.legend() # 凡例 plt.show() # 描画
x・y・z軸それぞれの方向に変化した点が赤・ピンク・オレンジ色の点、全ての方向に変化した点が黄緑色の点です。各点がバーの先端になっているのを確認できます。
全ての方向への変化を表す実線のベクトルは、各軸への変化を表す破線のベクトルを足したものです。
・作図コード(クリックで展開)
# 3D棒グラフを作成 fig = plt.figure(figsize=(9, 8)) # 図の設定 ax = fig.add_subplot(projection='3d') # 3D用の設定 ax.bar3d(x=x, y=y, z=z, dx=dx, dy=dy, dz=dz, color='white', alpha=0.25) # 3D棒グラフ ax.scatter(xs=x, ys=y, zs=z, s=100, color='purple', label='(x, y, z)') # 起点 ax.scatter(xs=x+dx, ys=y, zs=z, s=100, color='red', label='(x+dx, y, z)') # x軸方向に変化した点 ax.scatter(xs=x+dx, ys=y+dy, zs=z, s=100, color='aqua', label='(x+dx, y+dy, z)') # x軸とy軸方向に変化した点 ax.scatter(xs=x+dx, ys=y+dy, zs=z+dz, s=100, color='springgreen', label='(x+dx, y+dy, z+dz)') # 全ての軸で変化した点 ax.quiver(x, y, z, dx, 0.0, 0.0, color='purple', linestyle=':', arrow_length_ratio=0.1) # x軸の変化量 ax.quiver(x+dx, y, z, 0.0, dy, 0.0, color='purple', linestyle=':', arrow_length_ratio=0.1) # y軸の変化量 ax.quiver(x+dx, y+dy, z, 0.0, 0.0, dz, color='purple', linestyle=':', arrow_length_ratio=0.1) # z軸の変化量 ax.quiver(x, y, z, dx, dy, dz, color='purple', arrow_length_ratio=0.1) # xの変化量 ax.set_xlabel('x') # x軸ラベル ax.set_ylabel('y') # y軸ラベル ax.set_zlabel('z') # z軸ラベル ax.set_title('bar3d', fontsize='20') # タイトル fig.legend() # 凡例 plt.show() # 描画
足す順番に関わらず黄緑色の点を指します。
dx, dy, dz
がそれぞれバーの幅・奥行き・高さの値なのを確認できます。
入力$x, y$に対応する出力$z$のようなデータの場合は、$x, y$がx, y
で$z$がdz
に対応しています。
起点の調整
バーの底面の中心に点$(x, y, z)$がくるように調整します。
バーのサイズを指定します。
# 起点を指定 x = 0.0 y = 0.0 z = 0.0 # バーのハーフサイズの値を指定 a = 0.5 # 変化量を指定 dx = a * 2.0 dy = a * 2.0 dz = 1.0
バーの幅・奥行きのサイズの半分の値をa
として指定します。幅・奥行きのサイズdx, dy
はa
の2倍の値とします。
a
を使って起点をズラして3D棒グラフを作成します。
# デフォルトの設定 fig = plt.figure(figsize=(9, 8)) # 図の設定 ax = fig.add_subplot(projection='3d') # 3D用の設定 ax.bar3d(x=x, y=y, z=z, dx=dx, dy=dy, dz=dz, color='white', alpha=0.5) # 3D棒グラフ ax.scatter(xs=x, ys=y, zs=z, s=100, color='purple', label='(x, y, z)') # 起点 ax.quiver(x, y, z, dx, 0.0, 0.0, color='purple', linestyle='--', arrow_length_ratio=0.1) # x軸の変化量 ax.quiver(x, y, z, 0.0, dy, 0.0, color='purple', linestyle='--', arrow_length_ratio=0.1) # y軸の変化量 ax.quiver(x, y, z, 0.0, 0.0, dz, color='purple', linestyle='--', arrow_length_ratio=0.1) # z軸の変化量 ax.set_xlabel('x') # x軸ラベル ax.set_ylabel('y') # y軸ラベル ax.set_zlabel('z') # z軸ラベル ax.set_title('(x, y, z)', fontsize='20') # タイトル fig.legend() # 凡例 #ax.view_init(elev=90, azim=270) # 表示アングル plt.show() # 描画 # 起点をズラす fig = plt.figure(figsize=(9, 8)) # 図の設定 ax = fig.add_subplot(projection='3d') # 3D用の設定 ax.bar3d(x=x-a, y=y-a, z=z, dx=dx, dy=dy, dz=dz, color='white', alpha=0.5) # 3D棒グラフ ax.scatter(xs=x, ys=y, zs=z, color='purple', s=100, label='(x, y, z)') # 元の起点 ax.scatter(xs=x-a, ys=y-a, zs=z, color='green', s=100, label='(x-' + str(a) + ', y-' + str(a) + ', z)') # 調整後の起点 ax.quiver(x-a, y-a, z, dx, 0.0, 0.0, color='green', linestyle='--', arrow_length_ratio=0.1) # x軸の変化量 ax.quiver(x-a, y-a, z, 0.0, dy, 0.0, color='green', linestyle='--', arrow_length_ratio=0.1) # y軸の変化量 ax.quiver(x-a, y-a, z, 0.0, 0.0, dz, color='green', linestyle='--', arrow_length_ratio=0.1) # z軸の変化量 ax.set_xlabel('x') # x軸ラベル ax.set_ylabel('y') # y軸ラベル ax.set_zlabel('z') # z軸ラベル ax.set_title('(x-a, y-a, z)', fontsize='20') # タイトル fig.legend() # 凡例 #ax.view_init(elev=90, azim=270) # 表示アングル plt.show() # 描画
Axes.bar3d()
の引数x, y
にa
を引いた値x-a, y-a
を指定します。
元の図では紫色の点$(x = 0, y = 0, z = 0)$が底面の角だったのに対して、調整後の図は底面の中心になっています。代わりに、緑色の点$(x = -a, y = -a, z = 0)$が角になっています。
続いて、複数の場合を考えます。
バーの起点を作成します。
# 値を作成 vals = np.arange(3) # 格子点を作成 X, Y = np.meshgrid(vals, vals) # 起点を設定 x = X.flatten() y = Y.flatten() z = np.zeros_like(x) print(x) print(y) print(z)
[0 1 2 0 1 2 0 1 2]
[0 0 0 1 1 1 2 2 2]
[0 0 0 0 0 0 0 0 0]
簡単な例として、x・y軸は0, 1, 2
、z軸は0
の点とします。
1つの点のときと同様に、バーの半分のサイズを指定して幅・奥行き・高さを作成します。
# バーのハーフサイズの値を指定 a = 0.5 # 変化量を指定 dx = np.repeat(a=a * 2.0, repeats=len(x)) dy = np.repeat(a=a * 2.0, repeats=len(y)) dz = np.arange(len(z)) print(dx) print(dy) print(dz)
[1. 1. 1. 1. 1. 1. 1. 1. 1.] [1. 1. 1. 1. 1. 1. 1. 1. 1.] [0 1 2 3 4 5 6 7 8]
dx, dy
は、a
の2倍の値を起点と同じ数に複製します。dz
は、簡単な例として0
から1
ずつ増える値とします。
さきほどと同じコードで作図できます。
全ての点$(x, y, z)$がそれぞれのバーの底面の中心になっているのを確認できます。
a
の値を小さくするとバーに間隔を空けられます。
a
を0.4にするとバーが細くなり、バーの間に0.2の間隔を空けられます。
幅を持たない棒グラフも作成できます。
・作図コード(クリックで展開)
# バーのハーフサイズの値を指定 a = 0.4 # 変化量を指定 dx = np.repeat(a=a * 2.0, repeats=len(x)) dy = np.repeat(a=0.0, repeats=len(y)) # y軸方向の幅が0のグラフ fig = plt.figure(figsize=(9, 8)) # 図の設定 ax = fig.add_subplot(projection='3d') # 3D用の設定 ax.bar3d(x=x-a, y=y, z=z, dx=dx, dy=dy, dz=dz, color='white', alpha=0.5) # 3D棒グラフ ax.scatter(xs=x, ys=y, zs=z, color='purple', s=100, label='(x, y, z)') # 元の起点 ax.scatter(xs=x-a, ys=y, zs=z, color='green', s=100, label='(x-' + str(a) + ', y, z)') # 調整後の起点 ax.quiver(x-a, y, z, dx, 0.0, 0.0, color='green', linestyle='--', arrow_length_ratio=0.1) # x軸の変化量 ax.quiver(x-a, y, z, 0.0, dy, 0.0, color='green', linestyle='--', arrow_length_ratio=0.1) # y軸の変化量 ax.quiver(x-a, y, z, 0.0, 0.0, dz, color='green', linestyle='--', arrow_length_ratio=0.1) # z軸の変化量 ax.set_xlabel('x') # x軸ラベル ax.set_ylabel('y') # y軸ラベル ax.set_zlabel('z') # z軸ラベル ax.set_title('(x-a, y, z)', fontsize='20') # タイトル fig.legend() # 凡例 #ax.view_init(elev=90, azim=270) # 表示アングル plt.show() # 描画
# バーのハーフサイズの値を指定 a = 0.4 # 変化量を指定 dx = np.repeat(a=0.0, repeats=len(x)) dy = np.repeat(a=a * 2.0, repeats=len(y)) # x軸方向の幅が0のグラフ fig = plt.figure(figsize=(9, 8)) # 図の設定 ax = fig.add_subplot(projection='3d') # 3D用の設定 ax.bar3d(x=x, y=y-a, z=z, dx=dx, dy=dy, dz=dz, color='white', alpha=0.5) # 3D棒グラフ ax.scatter(xs=x, ys=y, zs=z, color='purple', s=100, label='(x, y, z)') # 元の起点 ax.scatter(xs=x, ys=y-a, zs=z, color='green', s=100, label='(x, y-' + str(a) + ', z)') # 調整後の起点 ax.quiver(x, y-a, z, dx, 0.0, 0.0, color='green', linestyle='--', arrow_length_ratio=0.1) # x軸の変化量 ax.quiver(x, y-a, z, 0.0, dy, 0.0, color='green', linestyle='--', arrow_length_ratio=0.1) # y軸の変化量 ax.quiver(x, y-a, z, 0.0, 0.0, dz, color='green', linestyle='--', arrow_length_ratio=0.1) # z軸の変化量 ax.set_xlabel('x') # x軸ラベル ax.set_ylabel('y') # y軸ラベル ax.set_zlabel('z') # z軸ラベル ax.set_title('(x, y-a, z)', fontsize='20') # タイトル fig.legend() # 凡例 #ax.view_init(elev=90, azim=270) # 表示アングル plt.show() # 描画
この図は、x軸とy軸のサイズを分けてax, ay
として片方を0にすることでも再現できます。
ここまでは、3D棒グラフのバーについて確認しました。以降は装飾について確認します。この資料の作図コードは概ねスカラ・複数どちらでも処理できます。
shade引数
shade
引数は、棒グラフの陰影を設定します。
shade=True
を指定します。
# 影を付ける:(デフォルト) fig = plt.figure(figsize=(9, 8)) # 図の設定 ax = fig.add_subplot(projection='3d') # 3D用の設定 ax.bar3d(x=x, y=y, z=z, dx=dx, dy=dy, dz=dz, shade=True) # 3D棒グラフ ax.set_xlabel('x') # x軸ラベル ax.set_ylabel('y') # y軸ラベル ax.set_zlabel('z') # z軸ラベル ax.set_title('shade=True', fontsize='20') # タイトル #ax.view_init(elev=90, azim=270) # 表示アングル plt.show() # 描画
陰影が入ることで立体的に見えます。True
がデフォルトの設定なので、shade
引数を指定しなくても陰影が付きます。
shade=False
を指定します。
# 影を消す fig = plt.figure(figsize=(9, 8)) # 図の設定 ax = fig.add_subplot(projection='3d') # 3D用の設定 ax.bar3d(x=x-a, y=y-a, z=z, dx=dx, dy=dy, dz=dz, shade=False) # 3D棒グラフ ax.set_xlabel('x') # x軸ラベル ax.set_ylabel('y') # y軸ラベル ax.set_zlabel('z') # z軸ラベル ax.set_title('shade=False', fontsize='20') # タイトル #ax.view_init(elev=90, azim=270) # 表示アングル plt.show() # 描画
濃淡のないフラットな色合いになります。
color引数
color
引数は、棒グラフの色を設定します。これまでのように、色名を指定することでバーの色を設定できます。ここでは、カラーマップによる設定を行います。
まずは、z軸の値をカラーマップに応じた色に変換する方法を確認します。この処理は、理解しなくても使えるので、飛ばしても問題ありません。
# カラーマップを指定 cm = plt.get_cmap('jet') # RGBA情報に変換 print(cm(0.5))
(0.4901960784313725, 1.0, 0.4775458570524984, 1.0)
pyplot.get_cmap()
にカラーマップ名を指定すると、0
から1
の値を対応する色に変換する関数を返します。その関数をcm()
として利用します。
cm()
は、入力した値を4つの値に変換して出力します。4つの値は、RGBA情報(色情報)と言い、赤色(R)・緑色(G)・青色(B)・透過度(A)を表します。
z
を最大値で割ることで0
から1
の値に正規化してから、cm()
で変換します。
# RGB情報に変換 print(dz / np.max(dz)) print(cm(dz / np.max(dz)))
[0. 0.125 0.25 0.375 0.5 0.625 0.75 0.875 1. ]
[[0. 0. 0.5 1. ]
[0. 0.00196078 1. 1. ]
[0. 0.50392157 1. 1. ]
[0.08538899 1. 0.88235294 1. ]
[0.49019608 1. 0.47754586 1. ]
[0.89500316 1. 0.07273877 1. ]
[1. 0.58169935 0. 1. ]
[1. 0.11692084 0. 1. ]
[0.5 0. 0. 1. ]]
dz
の要素ごとに4つの値に変換されます。
この結果をcolor
引数に指定します。
# カラーマップを指定 fig = plt.figure(figsize=(9, 8)) # 図の設定 ax = fig.add_subplot(projection='3d') # 3D用の設定 ax.bar3d(x=x-a, y=y-a, z=z, dx=dx, dy=dy, dz=dz, color=cm(dz / np.max(dz)), alpha=0.5) # 3D棒グラフ ax.set_xlabel('x') # x軸ラベル ax.set_ylabel('y') # y軸ラベル ax.set_zlabel('z') # z軸ラベル ax.set_title("cmap='jet'", fontsize='20') # タイトル plt.show() # 描画
jet
は青色から赤色に変化し、vridis
だと紫色から黄色に変化します。利用できるカラーマップについては、「Choosing Colormaps in Matplotlib — Matplotlib 3.5.1 documentation」を参照してください。
edgecolor引数
edgecolor
引数は、棒グラフの辺の色を設定します。
color
に指定した色情報を、そのままedgecolor
に指定してみます。
# カラーマップを指定 cm = plt.get_cmap('rainbow') # デフォルトの設定 fig = plt.figure(figsize=(9, 8)) # 図の設定 ax = fig.add_subplot(projection='3d') # 3D用の設定 ax.bar3d(x=x-a, y=y-a, z=z, dx=dx, dy=dy, dz=dz, color=cm(dz / np.max(dz)), edgecolor=cm(dz / np.max(dz)), alpha=0.5) # 3D棒グラフ ax.set_xlabel('x') # x軸ラベル ax.set_ylabel('y') # y軸ラベル ax.set_zlabel('z') # z軸ラベル ax.set_title('edgecolor=cm(...)', fontsize='20') # タイトル plt.show() # 描画
面の色と辺の色が異なっています。また、1つのバーでも辺の色が違うのが分かります。
面と辺の色を一致させるには、1つのバーに対して6個の色情報を設定する必要があります。
# 面と辺の色を一致させる fig = plt.figure(figsize=(9, 8)) # 図の設定 ax = fig.add_subplot(projection='3d') # 3D用の設定 ax.bar3d(x=x-a, y=y-a, z=z, dx=dx, dy=dy, dz=dz, color=cm(dz / np.max(dz)), edgecolor=cm(np.repeat(dz / np.max(dz), 6)), alpha=0.5) # 3D棒グラフ ax.set_xlabel('x') # x軸ラベル ax.set_ylabel('y') # y軸ラベル ax.set_zlabel('z') # z軸ラベル ax.set_title('edgecolor=cm(np.repeat(..., 6))', fontsize='20') # タイトル plt.show() # 描画
np.repeat()
で色情報を6個ずつ複製して引数に渡します。
詳しく確認してみます。飛ばしても問題ありません。
・作図コード(クリックで展開)
# カラーマップを指定 cm = plt.get_cmap('rainbow') # カラーマップを確認 plt.figure(figsize=(9, 8)) # 図の設定 plt.scatter(np.arange(6), np.arange(6), color=cm(np.arange(6) / 5), s=250) # 散布図 plt.grid() # グリッド線 plt.title("cmap='rainbow'", fontsize=20) # タイトル plt.show() # 描画
Rainbow
からこの6つの色を使います。
1つの点に対して6つの色を指定してみます。
・作図コード(クリックで展開)
# 辺の色付け順を確認 fig = plt.figure(figsize=(9, 8)) # 図の設定 ax = fig.add_subplot(projection='3d') # 3D用の設定 ax = fig.add_subplot(projection='3d') # 3D用の設定 ax.bar3d(x=-0.5, y=-0.5, z=0.0, dx=1.0, dy=1.0, dz=1.0, color='white', edgecolors=cm(np.arange(6) / 5), linewidth=5, alpha=0.5) # 3D棒グラフ ax.text(x=0.0, y=0.0, z=0.0, s='-Z', color=cm(0 / 5), fontsize=20) # -Zの面 ax.text(x=0.0, y=0.0, z=1.0, s='+Z', color=cm(1 / 5), fontsize=20) # +Zの面 ax.text(x=0.0, y=-0.5, z=0.5, s='-Y', color=cm(2 / 5), fontsize=20) # -Yの面 ax.text(x=0.0, y=0.5, z=0.5, s='+Y', color=cm(3 / 5), fontsize=20) # +Yの面 ax.text(x=-0.5, y=0.0, z=0.5, s='-X', color=cm(4 / 5), fontsize=20) # -Xの面 ax.text(x=0.5, y=0.0, z=0.5, s='+X', color=cm(5 / 5), fontsize=20) # +Xの面 ax.set_xlabel('x') # x軸ラベル ax.set_ylabel('y') # y軸ラベル ax.set_zlabel('z') # z軸ラベル ax.set_title('edgecolors=[-Z, +Z, -Y, +Y, -X, +X]', fontsize='20') # タイトル #ax.view_init(elev=0, azim=270) # 表示アングル plt.show() # 描画
色々な向きから確認できるようにアニメーションで確認します。
・作図コード(クリックで展開)
# 追加で利用するモジュール from matplotlib.animation import FuncAnimation # 作図用の角度を作成 v_vals = np.arange(start=-90.0, stop=270.0, step=3.0) h_vals = np.arange(start=0.0, stop=360.0, step=3.0) # カラーマップを指定 cm = plt.get_cmap('rainbow') # 図を初期化 fig = plt.figure(figsize=(9, 8)) ax = fig.add_subplot(projection='3d') # 3D用の設定 # 作図処理を関数として定義 def update(i): # 前フレームのグラフを初期化 plt.cla() # i回目の角度を取得 #v = 0.0 h = 270.0 v = v_vals[i] #h = h_vals[i] # 3D棒グラフを作成 ax.bar3d(x=-0.5, y=-0.5, z=0.0, dx=1.0, dy=1.0, dz=1.0, color='white', edgecolors=cm(np.arange(6) / 5), linewidth=5, alpha=0.5) # 3D棒グラフ ax.text(x=0.0, y=0.0, z=0.0, s='-Z', color=cm(0 / 5), fontsize=20) # -Zの面 ax.text(x=0.0, y=0.0, z=1.0, s='+Z', color=cm(1 / 5), fontsize=20) # +Zの面 ax.text(x=0.0, y=-0.5, z=0.5, s='-Y', color=cm(2 / 5), fontsize=20) # -Yの面 ax.text(x=0.0, y=0.5, z=0.5, s='+Y', color=cm(3 / 5), fontsize=20) # +Yの面 ax.text(x=-0.5, y=0.0, z=0.5, s='-X', color=cm(4 / 5), fontsize=20) # -Xの面 ax.text(x=0.5, y=0.0, z=0.5, s='+X', color=cm(5 / 5), fontsize=20) # +Xの面 ax.set_xlabel('x') # x軸ラベル ax.set_ylabel('y') # y軸ラベル ax.set_zlabel('z') # z軸ラベル if v < 0: # (270 < v < 360の範囲で軸が反転する対策) ax.set_title('v=' + str(np.round(360.0 + v)) + ', h=' + str(np.round(h))) # タイトル elif v >= 0: ax.set_title('v=' + str(np.round(v)) + ', h=' + str(np.round(h))) # タイトル ax.view_init(elev=v, azim=h) # 表示アングル # gif画像を作成 anime_bar3d = FuncAnimation(fig, update, frames=len(v_vals), interval=100) # gif画像を保存 anime_bar3d.save('bar3d.gif')
$270^{\circ} < v < 360^{\circ}$の範囲でx・y軸が反転するようで、$-90^{\circ} \leq v < 270^{\circ}$の範囲で描画します(負の値の角度はプログラム上$-90^{\circ} = 270^{\circ}$なはず(?)ですが、こちらだと軸が反転しないようです(謎))。
edgecolor
に指定した6つの色情報は、6つの面-Z, +Z, -Y, +Y, -X, +Z
の順に割り当てられます。-Z
は点$(0, 0, 0)$がある面を表し、同様に+Z
は$(0, 0, dz)$・-Y
は$(0, -a, \frac{dz}{2})$・+Y
は$(0, a, \frac{dz}{2})$・-X
は$(-a, 0, \frac{dz}{2})$・+X
は$(a, 0, \frac{dz}{2})$です。
各面を構成する4つの辺が同じ色になります。また、1つの辺は2つの面に接しているので、2つの色が割り当てられています。そのため、アニメーションから分かるように、表示する角度によって色が変わります。
軸目盛の設定
軸目盛を設定します。
Axes.set_*ticks()
で各軸の目盛を表示する値(位置)を設定できます。
# 軸目盛の表示位置を指定 fig = plt.figure(figsize=(9, 8)) # 図の設定 ax = fig.add_subplot(projection='3d') # 3D用の設定 ax.bar3d(x=x-a, y=y-a, z=z, dx=dx, dy=dy, dz=dz, color=cm(dz / np.max(dz)), alpha=0.5) # 3D棒グラフ ax.set_xlabel('x') # x軸ラベル ax.set_ylabel('y') # y軸ラベル ax.set_zlabel('z') # z軸ラベル ax.set_title('ticks', fontsize='20') # タイトル ax.set_xticks(ticks=vals) # x軸目盛 ax.set_yticks(ticks=vals) # y軸目盛 plt.show() # 描画
ticks
引数に表示する値を指定します。
さらに、Axes.set_*ticklabels()
で軸目盛のラベルを設定できます。
# 軸目盛の表示位置と文字列を指定 fig = plt.figure(figsize=(9, 8)) # 図の設定 ax = fig.add_subplot(projection='3d') # 3D用の設定 ax.bar3d(x=x-a, y=y-a, z=z, dx=dx, dy=dy, dz=dz, color=cm(dz / np.max(dz)), alpha=0.5) # 3D棒グラフ ax.set_xlabel('x') # x軸ラベル ax.set_ylabel('y') # y軸ラベル ax.set_zlabel('z') # z軸ラベル ax.set_title('ticks, ticklabels', fontsize='20') # タイトル ax.set_xticks(ticks=vals) # x軸目盛 ax.set_yticks(ticks=vals) # y軸目盛 ax.set_xticklabels(labels=['a', 'b', 'c']) # x軸目盛ラベル ax.set_yticklabels(labels=['A', 'B', 'C']) # y軸目盛ラベル plt.show() # 描画
Axes.set_*ticks()
で設定した位置に、labels
引数に指定した文字列が表示されます。
これまでは、x, y
引数に指定する値を調整することでバーの中心を調整しました。軸目盛を調整することでも再現できます。
# 起点を変更せずに目盛によって調整する fig = plt.figure(figsize=(9, 8)) # 図の設定 ax = fig.add_subplot(projection='3d') # 3D用の設定 ax.bar3d(x=x, y=y, z=z, dx=a*2.0, dy=a*2.0, dz=dz, color=cm(dz / np.max(dz)), alpha=0.5) # 3D棒グラフ ax.set_xlabel('x') # x軸ラベル ax.set_ylabel('y') # y軸ラベル ax.set_zlabel('z') # z軸ラベル ax.set_title('ticks, ticklabels', fontsize='20') # タイトル ax.set_xticks(ticks=vals + a) # x軸目盛 ax.set_yticks(ticks=vals + a) # y軸目盛 ax.set_xticklabels(labels=vals) # x軸目盛ラベル ax.set_yticklabels(labels=vals) # y軸目盛ラベル plt.show() # 描画
ax.bar3d()
の引数x, y
にそのままの値x, y
を指定し、軸目盛の位置をa
分ズラした位置に元の値を表示します。
「基本形の確認」と同様に確認してみます。
・作図コード(クリックで展開)
# 調整の結果を確認 fig = plt.figure(figsize=(9, 8)) # 図の設定 ax = fig.add_subplot(projection='3d') # 3D用の設定 ax.bar3d(x=x, y=y, z=z, dx=a*2.0, dy=a*2.0, dz=dz, color='white', alpha=0.5) # 3D棒グラフ ax.quiver(x, y, z, dx, 0.0, 0.0, color='purple', linestyle='--', arrow_length_ratio=0.1) # x軸 ax.quiver(x, y, z, 0.0, dy, 0.0, color='purple', linestyle='--', arrow_length_ratio=0.1) # y軸 ax.quiver(x, y, z, 0.0, 0.0, dz, color='purple', linestyle='--', arrow_length_ratio=0.1) # z軸 ax.scatter(xs=x, ys=y, zs=z, s=100, color='purple', label='(x, y, z)') # 元の起点 ax.scatter(xs=x-a, ys=y-a, zs=z, color='green', s=100, label='(x-' + str(a) + ', y-' + str(a) + ', z)') # 実際に調整したときの起点 ax.scatter(xs=x+a, ys=y+a, zs=z, color='mediumblue', s=100, label='(x+' + str(a) + ', y+' + str(a) + ', z)') # 見掛け上の調整後の中心 ax.set_xlabel('x') # x軸ラベル ax.set_ylabel('y') # y軸ラベル ax.set_zlabel('z') # z軸ラベル ax.set_title('ticks, ticklabels', fontsize='20') # タイトル ax.set_xticks(ticks=vals + a) # x軸目盛 ax.set_yticks(ticks=vals + a) # y軸目盛 ax.set_xticklabels(labels=vals) # x軸目盛ラベル ax.set_yticklabels(labels=vals) # y軸目盛ラベル fig.legend() # 凡例 #ax.view_init(elev=90, azim=270) # 表示アングル plt.show() # 描画
元の値(紫色の点)がバーの角のままで、x軸とy軸方向にa
を加えた値(青色の点)がバーの底面の中心になっているのを確認できます。
カラーバーの表示
カラーバーを設定します。
Mappable
オブジェクトを使ってカラーバーを表示します。
# カラーマップを指定 cm = plt.get_cmap('jet') # 3D棒グラフの作成 fig = plt.figure(figsize=(9, 8)) # 図の設定 ax = fig.add_subplot(projection='3d') # 3D用の設定 bar = ax.bar3d(x=x-a, y=y-a, z=z, dx=dx, dy=dy, dz=dz, color=cm(dz / np.max(dz)), edgecolor=cm(np.repeat(dz / np.max(dz), 6)), alpha=0.5) # 3D棒グラフ ax.set_xlabel('x') # x軸ラベル ax.set_ylabel('y') # y軸ラベル ax.set_zlabel('z') # z軸ラベル ax.set_title('bar3d', fontsize='20') # タイトル mappable = plt.cm.ScalarMappable(cmap='jet') # Mappableオブジェクト mappable.set_array(dz) # Mappableに値を設定 cbar = plt.colorbar(mappable, shrink=0.75, aspect=10) # カラーバー cbar.set_label('z') # カラーバーラベル #ax.view_init(elev=0, azim=300) # 表示アングル plt.show() # 描画
Pyplot.cm.ScalarMappable()
のcmap
引数にカラーマップ名を指定すると、対応するMappableオブジェクトが出力されます。
appable
のset_array()
メソッドにカラーマップと対応付ける値を指定します。
Pyplot.colorbar()
の第1引数にmappable
を指定してカラーバーを表示します。サイズは、引数shrink, aspect
で調整できます。shrink
は、図全体に対するカラーバーの高さの比率です。aspect
は、カラーバーの横幅に対する高さの比です。
cbar
のset_label()
メソッドでカラーバーにラベルを設定できます。
以上で、3D棒グラフを作成できました。
おわりに
悪名高き3D棒グラフ、だけど多項分布のグラフを描くのに必要だったんだよぅ。で思いのほか面倒だったのでブログにしておきます。目的のこちらも参考にしてみてください。
さて、さきほど公開された新MVをどうぞ。
初単独ホールツアーに初単独日本武道館公演決定めでたいっ!行きたいーっ