[Matplotlib] 3D 산점도의 밑면에 이미지를 삽입해 보았다
9488 단어 pandas파이썬matplotlibAnacondanumpy
소개
졸업 연구 과정에서 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()
실행 결과
주의점
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()
실행 결과
주의점
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
에 대상 이미지를 놓고 그것을 참조해 주고 싶은 것. 참고문헌
Reference
이 문제에 관하여([Matplotlib] 3D 산점도의 밑면에 이미지를 삽입해 보았다), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/momosuke/items/79fb4353dba74d40c9c1텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)