표면도:매트플롯립
3D 공간의 점 집합을 나타내는 3-튜플 목록이 있습니다.저는 이 모든 점을 포함하는 표면을 그려보고 싶습니다.
그plot_surface
에서 합니다.mplot3d
패키지는 인수 X, Y 및 Z가 2d 배열이어야 합니다.plot_surface
표면도면을 그리는 올바른 기능과 데이터를 필요한 형식으로 변환하는 방법은 무엇입니까?
data = [(x1,y1,z1),(x2,y2,z2),.....,(xn,yn,zn)]
표면의 경우 3-튜플 목록과 약간 다르므로 2D 배열의 도메인에 대한 그리드를 전달해야 합니다.
있는 기능이 포인트의 일 경우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
저는 방금 같은 문제를 발견했습니다.2-D 어레이 대신 31-D 어레이에 있는 균일한 간격의 데이터가 있습니다.matplotlib
의plot_surface
제자는우도히연에 .pandas.DataFrame
여기 31-D 배열을 플롯하기 위한 수정 사항이 있는 예제가 있습니다.
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')
그것이 원래의 예입니다.이 다음 비트를 추가하면 31-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()
다음은 결과 수치입니다.
마침 이매뉴얼은 제가 (아마도 많은 다른 사람들도) 찾고 있는 답을 가지고 있었습니다.3D 분산 데이터가 3개의 개별 어레이에 있는 경우 판다는 다른 옵션보다 훨씬 효과적이며 매우 유용합니다.자세히 설명하자면, x, y, z가 임의 변수라고 가정합니다.저의 경우 지원 벡터 머신을 테스트하고 있었기 때문에 c, 감마 및 오류가 발생했습니다.데이터를 표시할 수 있는 옵션은 여러 가지가 있습니다.
- scatter3D(cParams, gamma, avg_errors_array) - 이것은 작동하지만 지나치게 단순합니다.
- plot_wireframe(cParams, gammas, avg_errors_array) - 이것은 작동하지만, 실제 과학 데이터의 대량 청크의 경우와 같이 데이터가 잘 정렬되지 않으면 보기 흉할 것입니다.
- ax.plot3D(cParams, 감마, avg_errors_array) - 와이어프레임과 유사
데이터의 와이어프레임 그림
데이터의 3차원 산포
코드는 다음과 같습니다.
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()
다음은 최종 출력입니다.
이것은 일반적인 해결책은 아니지만 구글에서 "matplotlib 표면도"를 입력하고 여기에 착륙한 많은 사람들에게 도움이 될 수 있습니다.
있다고 가정해 보겠습니다.data = [(x1,y1,z1),(x2,y2,z2),.....,(xn,yn,zn)]
그러면 다음을 사용하여 3개의 1-D 목록을 얻을 수 있습니다.x, y, z = zip(*data)
이제 3개의 1-D 리스트를 사용하여 3D 산점도를 만들 수 있습니다.
그러나 일반적으로 이 데이터를 표면도를 만드는 데 사용할 수 없는 이유는 무엇입니까?빈 3-D 그림을 고려하는 방법:
이제 "이산적인" 정규 그리드에서 (x, y)의 각 가능한 값에 대해 z 값이 있다고 가정하면 문제가 없고 실제로 표면도를 얻을 수 있습니다.
import numpy as np
from matplotlib import pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from matplotlib import cm
x = np.linspace(0, 10, 6) # [0, 2,..,10] : 6 distinct values
y = np.linspace(0, 20, 5) # [0, 5,..,20] : 5 distinct values
z = np.linspace(0, 100, 30) # 6 * 5 = 30 values, 1 for each possible combination of (x,y)
X, Y = np.meshgrid(x, y)
Z = np.reshape(z, X.shape) # Z.shape must be equal to X.shape = Y.shape
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.plot_surface(X, Y, Z)
ax.set_xlabel('X Label')
ax.set_ylabel('Y Label')
ax.set_zlabel('Z Label')
plt.show()
(x, y)의 모든 가능한 조합에 대해 z가 없으면 어떻게 됩니까?그런 다음 점(위의 빈 플롯에서 x-y 평면의 두 검은색 선이 교차하는 지점)에서 z의 값이 무엇인지 알 수 없습니다.무엇이든 될 수 있습니다. 우리는 그 지점에서 우리의 표면이 어떻게 '높음' 또는 '낮음'이어야 하는지 모릅니다(다른 함수를 사용하여 근사할 수 있지만,surface_plot
X.shape = Y.shape = Z.shape)에서 변수를 입력해야 합니다.
불규칙한 도메인 유형 문제를 가진 다른 사람들을 도울 수 있는 몇 가지 생각을 추가하기 위해서입니다.사용자가 3개의 벡터/목록, z가 사각형 그리드에 표면으로 표시되는 2D 솔루션을 나타내는 x,y,z가 있는 상황에서는 ArtixR의 'plot_trisurf()' 주석이 적용됩니다.유사하지만 직사각형이 아닌 도메인의 예는 다음과 같습니다.
import matplotlib.pyplot as plt
from matplotlib import cm
from mpl_toolkits.mplot3d import Axes3D
# problem parameters
nu = 50; nv = 50
u = np.linspace(0, 2*np.pi, nu,)
v = np.linspace(0, np.pi, nv,)
xx = np.zeros((nu,nv),dtype='d')
yy = np.zeros((nu,nv),dtype='d')
zz = np.zeros((nu,nv),dtype='d')
# populate x,y,z arrays
for i in range(nu):
for j in range(nv):
xx[i,j] = np.sin(v[j])*np.cos(u[i])
yy[i,j] = np.sin(v[j])*np.sin(u[i])
zz[i,j] = np.exp(-4*(xx[i,j]**2 + yy[i,j]**2)) # bell curve
# convert arrays to vectors
x = xx.flatten()
y = yy.flatten()
z = zz.flatten()
# Plot solution surface
fig = plt.figure(figsize=(6,6))
ax = Axes3D(fig)
ax.plot_trisurf(x, y, z, cmap=cm.jet, linewidth=0,
antialiased=False)
ax.set_title(r'trisurf example',fontsize=16, color='k')
ax.view_init(60, 35)
fig.tight_layout()
plt.show()
위의 코드는 다음을 생성합니다.
그러나 모든 문제, 특히 문제가 불규칙한 도메인에 정의된 경우 이 문제가 해결되지 않을 수 있습니다.또한 도메인에 하나 이상의 오목한 영역이 있는 경우, 지연 삼각 측량은 도메인 외부에 가짜 삼각형을 생성할 수 있습니다.이러한 경우 정확한 표면 표현을 달성하려면 삼각 측량에서 이러한 불량 삼각형을 제거해야 합니다.이러한 상황에서 사용자는 이러한 삼각형을 프로그래밍 방식으로 제거할 수 있도록 지연 삼각형 계산을 명시적으로 포함해야 할 수 있습니다.이러한 상황에서 다음 코드가 이전 플롯 코드를 대체할 수 있습니다.
import matplotlib.tri as mtri
import scipy.spatial
# plot final solution
pts = np.vstack([x, y]).T
tess = scipy.spatial.Delaunay(pts) # tessilation
# Create the matplotlib Triangulation object
xx = tess.points[:, 0]
yy = tess.points[:, 1]
tri = tess.vertices # or tess.simplices depending on scipy version
#############################################################
# NOTE: If 2D domain has concave properties one has to
# remove delaunay triangles that are exterior to the domain.
# This operation is problem specific!
# For simple situations create a polygon of the
# domain from boundary nodes and identify triangles
# in 'tri' outside the polygon. Then delete them from
# 'tri'.
# <ADD THE CODE HERE>
#############################################################
triDat = mtri.Triangulation(x=pts[:, 0], y=pts[:, 1], triangles=tri)
# Plot solution surface
fig = plt.figure(figsize=(6,6))
ax = fig.gca(projection='3d')
ax.plot_trisurf(triDat, z, linewidth=0, edgecolor='none',
antialiased=False, cmap=cm.jet)
ax.set_title(r'trisurf with delaunay triangulation',
fontsize=16, color='k')
plt.show()
예제 그림은 솔루션 1) 위의 삼각형과 2) 제거된 위치를 보여주는 아래와 같습니다.
위의 내용이 솔루션 데이터의 오목한 상황에 있는 사람들에게 도움이 되었으면 합니다.
공식 예제를 확인하십시오. X, Y 및 Z는 실제로 2d 배열입니다. numpy.meshgrid()는 1d x 및 y 값에서 2d x,y 메시를 얻는 간단한 방법입니다.
http://matplotlib.sourceforge.net/mpl_examples/mplot3d/surface3d_demo.py
여기 3-튜플을 31d 배열로 변환하는 파이썬적인 방법이 있습니다.
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)
다음은 mtapplotlib delaunay 삼각 측량(보간)으로, 1d x, y, z를 호환되는 것(?)으로 변환합니다.
http://matplotlib.sourceforge.net/api/mlab_api.html#matplotlib.mlab.griddata
Matlab에서 저는 비슷한 것을 했습니다.delaunay
에 대한 기능.x
,y
좌표만(가 아님)z
), 다음으로 그림을 표시합니다.trimesh
또는trisurf
,사용.z
높이만큼
SciPy에는 Delaunay 클래스가 있으며, 이 클래스는 Matlab의 클래스와 동일한 기본 QHull 라이브러리를 기반으로 합니다.delaunay
함수는 동일한 결과를 얻어야 합니다.
거기서부터, 파이썬-매트플롯립에서 이 3D 폴리곤을 당신이 성취하고자 하는 것으로 변환하는 것은 코드의 몇 줄이어야 합니다.Delaunay
각 삼각형 폴리곤의 사양을 제공합니다.
데이터를 사용하여 3D 표면을 직접 만들 수는 없습니다.저는 당신이 pykridge와 같은 도구를 사용하여 보간 모델을 구축하는 것을 추천합니다.이 프로세스에는 세 가지 단계가 포함됩니다.
- 다음을 사용하여 보간 모델 교육
pykridge
- 다음에서 그리드 구축
X
그리고.Y
사용.meshgrid
- 다음에 대한 값 보간
Z
그리드 및 해당 그리드를 작성한 경우Z
가치관, 이제 당신은 함께 할 준비가 되었습니다.plot_surface
참고로 데이터의 크기에 따라meshgrid
기능이 잠시 동안 실행될 수 있습니다.해결 방법은 다음을 사용하여 균일한 간격으로 샘플을 생성하는 것입니다.np.linspace
위해서X
그리고.Y
축을 선택한 다음 보간을 적용하여 필요한 값을 추론합니다.Z
만약 이 원래의 보간된 값과 수 .Z
X
그리고.Y
변했습니다.
언급URL : https://stackoverflow.com/questions/9170838/surface-plots-in-matplotlib
'programing' 카테고리의 다른 글
스프링 스케줄링 작업 - 한 번만 실행 (0) | 2023.08.25 |
---|---|
Powershell에서 -Verbose 인수가 주어졌는지 확인할 수 있습니까? (0) | 2023.08.25 |
프로그래밍 방식으로 "Windows 바탕 화면을 이 모니터로 확장" (0) | 2023.08.25 |
중앙값에 부스트 로그 라이브러리 누락OS 7 기본 레포 (0) | 2023.08.25 |
ASP.NET 그리드행 색인을 명령으로 보기인수 (0) | 2023.08.25 |