はじめに
matplotlibのmplot3d拡張を使って3D空間上のデータポイントにカスタム画像をマーカーとして表示する方法を解説します。この技術を使うことで、データ可視化をより直感的で情報豊かなものにすることができます。
コード

解説
モジュールのインポート
データの生成
np.random.rand(6,3)を使用して、0以上1未満の乱数値からなる6行3列のデータを生成します。
figの作成とプロット
Figureを作成し、データを散布図としてプロットし、軸ラベルを設定します。
画像を表示するためのダミーaxesの生成
同じfigの111の位置に3Dグラフと2Dグラフを重ねて作成し、2Dグラフ上に画像を表示します。ax2.axis([0,1,0,1])を設定することで、2DグラフをFigure全体に表示させます。
frame_on=Falseを指定すると背景が透明になり、ax2.axis(“off”)を実行すると軸と目盛りが非表示になります。
画像の読み込みとトリミング
この画像を読み込みます。

plt.imread(image_path)で画像を配列として読み込み、スライシングによりトリミングし、ロフォフォラだけが表示されるようにしています。
画像を表示する座標を求める関数
関数proj(X, ax1, ax2)は、3Dグラフの点を2次元に投影してデータ座標を求め、その投影データ座標をディスプレイ座標に変換し、最終的にそのディスプレイ座標をax2のデータ座標に変換する一連の処理を行います。
まず最初に、proj3d.proj_transform(x,y,z, ax1.get_proj())を使ってデータの投影を行います。得られたx2,y2をプロットすると次のようになります。

この3D座標を2Dディスプレイ座標に変換します。ax1.transData.transform((x2, y2))を実行した結果は以下のようになります。

このディスプレイ座標をax2のデータ座標に変換した結果、つまり、ax2.transData.inverted().transform(ax1.transData.transform((x2, y2)))の戻り値は以下のようになります。

画像を表示する関数
画像をOffsetImageに取り込む
imはmatplotlib.offsetbox.OffsetImageオブジェクトとして生成され、zoomパラメータを使用して画像の拡大縮小率を調整できます。
OffsetImageをAnnotationBboxに取り込んで表示
AnnotationBboxにより画像を表示します。 im, xy, xybox=(0,0)は、imをxyの位置から(0,0)離れた場所に表示することを意味するため、実質的にxyの位置に画像が表示されます。xycoords=’data’でxyの位置指定にデータ座標系が使用され、boxcoords=”offset points”では画像表示ボックスの位置調整にポイント座標系が使用されることを示しています。
ax.add_artist(ab)を実行することで、画像が図に追加・表示されます。
コードをダウンロード(.pyファイル) コードをダウンロード(.ipynbファイル)
コメント
[…] [matplotlib 3D] 52. 3Dグラフでマーカーとして画像を使用する方法matplotlib mplot3dによる3Dグラフ上でマーカーとして画像を表示する方法について解説する。sabopy.com2019.06.28 […]