[Matplotlib] 3D 산점도의 밑면에 이미지를 삽입해 보았다

소개



졸업 연구 과정에서 3D 산포도를 만들게 되었다.

구체적으로는 아이 트래킹의 연구시에 PC 화면에 화상을 표시시켜 피험자에게 일정 시간 보였을 때의 시선의 x 좌표, y 좌표, 시간 t의 3차원 데이터(csv)를 바탕으로 산포도를 만들 때 밑면(x, y면)에 보여준 이미지를 표시시키면 알기 쉽다고 생각한 것이 계기이다.

그러나 아무리 찾았지만 일본어 기사를 찾을 수 없었기 때문에 (2D 그래프의 배경 이미지 삽입은 간단하고 몇 가지 기사는 발견되었다).

감사 : Twitter에서 조언을 주신 선배님에게 이 자리를 빌려 진심으로 감사하고 싶다.

대상자·구원할 수 있는 사람



3D 그래프(산포도가 아니어도)를 만들 때에 밑면(나아가서는 x, y평면에 수평)에 임의의 화상을 표시하고 싶은 분.

운영 환경



anaconda로 환경 구축하면 모두 표준으로 인스톨 되고 있다.
- 파이썬 : 3.7
- matplotlib : 3.1.0
- pandas : 0.24.2
- numpy : 1.16.4
- 같은 디렉토리에 Python 파일과 csv 파일, 이미지 파일(2018.png)을 배치

코드



momosuke.py
# 諸々のモジュールのインポート
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from matplotlib import cm
from matplotlib.ticker import LinearLocator, FormatStrFormatter
from matplotlib._png import read_png
from matplotlib.cbook import get_sample_data
from pylab import *

# col_namesでカラム名を指定してcsvファイルを読み込む *
col_names = ['x', 'y', 't']
data = pd.read_csv('kisisan.csv', names=col_names)

# 分かりやすいようにそれぞれ配列へ格納(自分がpython初心者のため) *
listX = data["x"]
listY = data["y"]
listT = data["t"]
# データ数がめちゃ多かったので100ごとにスキップして再格納 *
listX = listX[::100]
listY = listY[::100]
listT = listT[::100]

# 3Dグラフを作る時のテンプレートみたいなもの(ax=のところの書き方は複数あるっぽい)
fig = plt.figure()
ax = Axes3D(fig)

# 挿入画像を読み込む
fn = get_sample_data("/Users/momosuke/eye-tracking-for-efficiency-improvement-of-transfer/2018.png", asfileobj=False)
arr = read_png(fn)

# 画像を挿入(1094000000のところは挿入するZ座標.0など任意の値にどうぞ)
X1, Y1 = ogrid[0:arr.shape[0], 0:arr.shape[1]]
ax.plot_surface(X1, Y1, np.atleast_2d(1094000000), rstride=5, cstride=5, facecolors=arr)

# メインの散布図を挿入 *
p = ax.scatter(listX, listY, listT, s=100, alpha=0.8, c=listT, cmap='hot', label='eye-position')
fig.colorbar(p)
ax.plot(listX, listY, listT, linewidth=3, color='lightsalmon')

# 各座標軸のラベルの設定
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('t')

# 描画
plt.show()

실행 결과





주의점


  • 코드에서 #의 설명문의 오른쪽에 *가 들어있는 것은 산포도에 관한 코드이므로 본제의 화상 삽입에는 관계 없으므로 적절히 무시하고 활용해 주었으면 한다.
  • 코드에서 get_sample_data()로 지정된 경로는 상대 경로가 아닌 절대 경로가되도록 권장합니다. 상대 경로로 설정하면 FileNotFoundError: [Errno 2] No such file or directory: '/Users/momosuke/anaconda3/lib/python3.7/site-packages/matplotlib/mpl-data/sample_data/2018.png'라는 오류가 발생합니다. 요컨대 상대 경로를 사용하고 싶다면 ~/sample_data에 대상 이미지를 놓고 그것을 참조해 주고 싶은 것.
  • 이 기사는 이미지를 삽입하는 방법을 제공하며 그래프의 미세한 매개 변수 설정을 생략하므로 세부 사항을 각각 조정해야합니다.

  • 참고문헌


  • Image overlay in 3d plot using python
  • Matplotlib: Show Backgroundimage in 3D Graph with plot_Surface
  • Python 3.7.4 문서
  • 좋은 웹페이지 즐겨찾기