matplotlib의 표면 플롯
3D 공간에서 일련의 점을 나타내는 3- 튜플 목록이 있습니다. 이 모든 점을 포함하는 표면을 플로팅하고 싶습니다. mplot3d 패키지의 plot_surface 함수에는 2d 배열 인 인수 X, Y 및 Z가 필요합니다. plot_surface는 표면을 그리는 데 적합한 함수이며 데이터를 필요한 형식으로 어떻게 변환합니까?
data = [(x1,y1,z1),(x2,y2,z2),.....,(xn,yn,zn)]
표면의 경우 3- 튜플 목록과 약간 다르므로 2d 배열의 도메인에 대한 그리드를 전달해야합니다.
일부 기능이 아닌 3D 점 목록 만 f(x, y) -> z
있으면 해당 3D 점 구름을 지표면으로 삼각 측량하는 여러 방법이 있기 때문에 문제가 발생합니다.
다음은 매끄러운 표면의 예입니다.
import numpy as np
from mpl_toolkits.mplot3d import Axes3D
# Axes3D import has side effects, it enables using projection='3d' in add_subplot
import matplotlib.pyplot as plt
import random
def fun(x, y):
return x**2 + y
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
x = y = np.arange(-3.0, 3.0, 0.05)
X, Y = np.meshgrid(x, y)
zs = np.array(fun(np.ravel(X), np.ravel(Y)))
Z = zs.reshape(X.shape)
ax.plot_surface(X, Y, Z)
ax.set_xlabel('X Label')
ax.set_ylabel('Y Label')
ax.set_zlabel('Z Label')
plt.show()
일부 파일에서 직접 데이터를 읽고 플롯 할 수 있습니다.
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
from matplotlib import cm
import numpy as np
from sys import argv
x,y,z = np.loadtxt('your_file', unpack=True)
fig = plt.figure()
ax = Axes3D(fig)
surf = ax.plot_trisurf(x, y, z, cmap=cm.jet, linewidth=0.1)
fig.colorbar(surf, shrink=0.5, aspect=5)
plt.savefig('teste.pdf')
plt.show()
필요한 경우 vmin 및 vmax를 전달하여 컬러 바 범위를 정의 할 수 있습니다.
surf = ax.plot_trisurf(x, y, z, cmap=cm.jet, linewidth=0.1, vmin=0, vmax=2000)
보너스 섹션
이 경우 인공 데이터를 사용하여 대화 형 플롯을 수행하는 방법을 궁금합니다.
from __future__ import print_function
from ipywidgets import interact, interactive, fixed, interact_manual
import ipywidgets as widgets
from IPython.display import Image
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import numpy as np
from mpl_toolkits import mplot3d
def f(x, y):
return np.sin(np.sqrt(x ** 2 + y ** 2))
def plot(i):
fig = plt.figure()
ax = plt.axes(projection='3d')
theta = 2 * np.pi * np.random.random(1000)
r = i * np.random.random(1000)
x = np.ravel(r * np.sin(theta))
y = np.ravel(r * np.cos(theta))
z = f(x, y)
ax.plot_trisurf(x, y, z, cmap='viridis', edgecolor='none')
fig.tight_layout()
interactive_plot = interactive(plot, i=(2, 10))
interactive_plot
나는 방금이 같은 문제를 만났습니다. I 균등 대신에 2-D 어레이 (3) 1-D 어레이에 데이터 이격 한 matplotlib
의 plot_surface
욕구를. 내 데이터가 a에 있었 pandas.DataFrame
으므로 여기에 3 개의 1-D 배열을 플롯하도록 수정 한 matplotlib.plot_surface
예가 있습니다.
from mpl_toolkits.mplot3d import Axes3D
from matplotlib import cm
from matplotlib.ticker import LinearLocator, FormatStrFormatter
import matplotlib.pyplot as plt
import numpy as np
X = np.arange(-5, 5, 0.25)
Y = np.arange(-5, 5, 0.25)
X, Y = np.meshgrid(X, Y)
R = np.sqrt(X**2 + Y**2)
Z = np.sin(R)
fig = plt.figure()
ax = fig.gca(projection='3d')
surf = ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap=cm.coolwarm,
linewidth=0, antialiased=False)
ax.set_zlim(-1.01, 1.01)
ax.zaxis.set_major_locator(LinearLocator(10))
ax.zaxis.set_major_formatter(FormatStrFormatter('%.02f'))
fig.colorbar(surf, shrink=0.5, aspect=5)
plt.title('Original Code')
그것이 원래의 예입니다. 이 다음 비트를 추가하면 3 개의 1-D 배열에서 동일한 플롯이 생성됩니다.
# ~~~~ MODIFICATION TO EXAMPLE BEGINS HERE ~~~~ #
import pandas as pd
from scipy.interpolate import griddata
# create 1D-arrays from the 2D-arrays
x = X.reshape(1600)
y = Y.reshape(1600)
z = Z.reshape(1600)
xyz = {'x': x, 'y': y, 'z': z}
# put the data into a pandas DataFrame (this is what my data looks like)
df = pd.DataFrame(xyz, index=range(len(xyz['x'])))
# re-create the 2D-arrays
x1 = np.linspace(df['x'].min(), df['x'].max(), len(df['x'].unique()))
y1 = np.linspace(df['y'].min(), df['y'].max(), len(df['y'].unique()))
x2, y2 = np.meshgrid(x1, y1)
z2 = griddata((df['x'], df['y']), df['z'], (x2, y2), method='cubic')
fig = plt.figure()
ax = fig.gca(projection='3d')
surf = ax.plot_surface(x2, y2, z2, rstride=1, cstride=1, cmap=cm.coolwarm,
linewidth=0, antialiased=False)
ax.set_zlim(-1.01, 1.01)
ax.zaxis.set_major_locator(LinearLocator(10))
ax.zaxis.set_major_formatter(FormatStrFormatter('%.02f'))
fig.colorbar(surf, shrink=0.5, aspect=5)
plt.title('Meshgrid Created from 3 1D Arrays')
# ~~~~ MODIFICATION TO EXAMPLE ENDS HERE ~~~~ #
plt.show()
결과 수치는 다음과 같습니다.
공식 예를 확인하십시오. X, Y 및 Z는 실제로 2d 배열이며 numpy.meshgrid ()는 1d x 및 y 값에서 2d x, y 메시를 얻는 간단한 방법입니다.
http://matplotlib.sourceforge.net/mpl_examples/mplot3d/surface3d_demo.py
3 튜플을 3 1d 배열로 변환하는 비단뱀적인 방법이 있습니다.
data = [(1,2,3), (10,20,30), (11, 22, 33), (110, 220, 330)]
X,Y,Z = zip(*data)
In [7]: X
Out[7]: (1, 10, 11, 110)
In [8]: Y
Out[8]: (2, 20, 22, 220)
In [9]: Z
Out[9]: (3, 30, 33, 330)
다음은 mtaplotlib delaunay 삼각 분할 (보간)입니다. 1d x, y, z를 호환되는 것으로 변환합니다 (?) :
http://matplotlib.sourceforge.net/api/mlab_api.html#matplotlib.mlab.griddata
임마누엘은 내가 (그리고 아마도 많은 다른 사람들이) 찾고있는 답을 얻었다. 3 개의 개별 배열에 3D 분산 데이터가있는 경우 pandas는 놀라운 도움이되며 다른 옵션보다 훨씬 더 잘 작동합니다. 자세히 설명하기 위해 x, y, z가 임의의 변수라고 가정합니다. 제 경우에는 서포트 벡터 머신을 테스트하고 있었기 때문에 c, 감마 및 오류였습니다. 데이터를 표시 할 수있는 여러 가지 잠재적 선택 사항이 있습니다.
- scatter3D (cParams, gammas, avg_errors_array)-작동하지만 지나치게 단순합니다.
- plot_wireframe (cParams, gammas, avg_errors_array)-작동하지만 데이터가 제대로 정렬되지 않으면 실제 과학 데이터가 방대한 청크가있는 경우처럼보기 흉하게 보일 것입니다.
- ax.plot3D (cParams, gammas, avg_errors_array)-와이어 프레임과 유사
데이터의 와이어 프레임 플롯
데이터의 3D 분산
코드는 다음과 같습니다.
fig = plt.figure()
ax = fig.gca(projection='3d')
ax.set_xlabel('c parameter')
ax.set_ylabel('gamma parameter')
ax.set_zlabel('Error rate')
#ax.plot_wireframe(cParams, gammas, avg_errors_array)
#ax.plot3D(cParams, gammas, avg_errors_array)
#ax.scatter3D(cParams, gammas, avg_errors_array, zdir='z',cmap='viridis')
df = pd.DataFrame({'x': cParams, 'y': gammas, 'z': avg_errors_array})
surf = ax.plot_trisurf(df.x, df.y, df.z, cmap=cm.jet, linewidth=0.1)
fig.colorbar(surf, shrink=0.5, aspect=5)
plt.savefig('./plots/avgErrs_vs_C_andgamma_type_%s.png'%(k))
plt.show()
최종 출력은 다음과 같습니다.
Matlab에서 나는 , coords 만 (아님 ) delaunay
함수를 사용하여 비슷한 작업을 한 다음 높이로 사용하여 또는으로 플로팅했습니다 .x
y
z
trimesh
trisurf
z
SciPy에는 Matlab의 함수 와 동일한 기본 QHull 라이브러리를 기반으로 하는 Delaunay 클래스 delaunay
가 있으므로 동일한 결과를 얻어야합니다.
거기 에서 python-matplotlib 예제의 Plotting 3D Polygons 를 원하는대로 변환하는 코드 몇 줄이 있어야합니다 Delaunay
. 각 삼각형 다각형의 사양이 제공됩니다.
데이터를 사용하여 3D 표면을 직접 만드는 것은 불가능합니다. pykridge 와 같은 도구를 사용하여 보간 모델을 구축하는 것이 좋습니다 . 이 프로세스에는 다음 세 단계가 포함됩니다.
- 다음을 사용하여 보간 모델 훈련
pykridge
- 에서 그리드 작성
X
및Y
사용meshgrid
- 값 보간
Z
그리드와 해당 Z
값 을 생성 했으므로 이제 plot_surface
. 데이터 크기에 따라 meshgrid
함수가 잠시 실행될 수 있습니다. 해결 방법은 np.linspace
for X
및 Y
축을 사용하여 균일 한 간격의 샘플을 만든 다음 보간을 적용하여 필요한 Z
값 을 추론하는 것 입니다. 이 경우, 보간 값은 원래 다른 수 Z
있기 때문 X
및 Y
변경되었습니다.
참고 URL : https://stackoverflow.com/questions/9170838/surface-plots-in-matplotlib
'programing' 카테고리의 다른 글
내 마스터 브랜치에서 "중간"커밋을 팝업하고 폐기해야합니다. (0) | 2020.09.14 |
---|---|
CSV Django 모듈을 사용하여 범용 줄 바꿈 모드로 파일 열기 (0) | 2020.09.14 |
테이블 행 내부에서 페이지 나누기 방지 (0) | 2020.09.14 |
2.x로 업그레이드하는 대신 Nuget을 jQuery 1.9.x / 1.x 경로에 유지할 수 있습니까? (0) | 2020.09.14 |
UIBezierPath가 Core Graphics 경로보다 빠른 이유는 무엇입니까? (0) | 2020.09.14 |