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
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个一维数组创建相同的图。
# ~~~~ 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()
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()
在Matlab中,我使用delaunay函数在x,y坐标上做了类似的事情(不是z),然后用trimesh或trisurf绘图,使用z作为高度。 SciPy有Delaunay类,它基于与Matlab的delaunay函数相同的底层QHull库,所以你应该得到相同的结果。 从那里开始,应该只需要几行代码就可以将这个Plotting 3D Polygons in python-matplotlib示例转换为您希望实现的内容,因为Delaunay为您提供了每个三角形多边形的规范。
9条答案
按热度按时间drkbr07n1#
对于曲面,它与三元组列表有点不同,你应该在2d数组中传入域的网格。
如果你只有一个3d点的列表,而不是一些函数
f(x, y) -> z
,那么你就会遇到问题,因为有多种方法可以将3d点云三角化为一个表面。下面是一个光滑曲面示例:
ctrmrzij2#
您可以直接从某些文件和图中读取数据
如果需要,你可以传递vmin和vmax来定义颜色条范围,例如:
奖励板块
我想知道如何做一些互动的情节,在这种情况下与人工数据
yyhrrdl83#
我也遇到了同样的问题。我有均匀间隔的数据,这些数据位于3个1-D数组中,而不是
matplotlib
的plot_surface
想要的2-D数组。我的数据碰巧在pandas.DataFrame
中,所以这里是matplotlib.plot_surface
示例,修改后绘制3个一维数组。这是最初的例子。添加下一位将从3个一维数组创建相同的图。
以下是得出的数字:
oxcyiej74#
只是插话,伊曼纽尔有我(可能还有许多其他人)正在寻找的答案。如果你在3个独立的数组中有3d分散的数据,pandas是一个令人难以置信的帮助,比其他选项好得多。为了详细说明,假设你的x,y,z是一些任意变量。在我的例子中,这些是c,gamma和errors,因为我正在测试支持向量机。有许多可能的选择来绘制数据:
数据的线框图
数据的三维散点
代码看起来像这样:
下面是最终的输出:
tyky79it5#
这不是一个通用的解决方案,但可能会帮助那些刚刚在谷歌输入“matplotlib surface plot”并登陆这里的人。
假设你有
data = [(x1,y1,z1),(x2,y2,z2),.....,(xn,yn,zn)]
,那么你可以用x, y, z = zip(*data)
得到三个一维列表。现在你当然可以使用三个一维列表来实现create 3d scatterplot。但是,为什么不能 * 一般 * 这些数据被用来创建表面图?为了理解这一点,考虑一个空的三维图:
现在,假设对于“离散”规则网格上(x,y)的每个可能值,您都有一个z值,那么就没有问题了&您实际上可以得到一个曲面图:
当你没有得到所有可能的(x,y)组合的z时会发生什么?然后在这一点上(在上面空白图上x-y平面上两条黑线的交点处),我们不知道z的值是多少。它可以是任何东西,我们不知道我们的表面在那一点上应该有多高或多低(尽管它可以使用其他函数近似,
surface_plot
要求你提供参数,其中X.shape = Y.shape = Z.shape)。goucqfw66#
只是添加一些进一步的想法,这可能会帮助其他人与不规则域类型的问题。对于用户具有三个矢量/列表x、y、z表示2D解决方案的情况,其中z将被绘制在矩形网格上作为表面,ArtifixR的'plot_trisurf()'注解是适用的。一个类似的但具有非矩形域的示例是:
上面的代码产生:
然而,这可能无法解决所有问题,特别是在不规则域上定义问题的情况下。而且,在域具有一个或多个凹区域的情况下,Delaunay三角测量可能导致生成域外部的虚假三角形。在这种情况下,必须从三角测量中移除这些不规则三角形,以实现正确的表面表示。对于这些情况,用户可能必须显式地包括delaunay三角测量计算,以便可以编程地移除这些三角形。在这些情况下,以下代码可以替换以前的绘图代码:
下面给出了示例图,其示出了具有伪三角形的解决方案1)和已经移除伪三角形的解决方案2):
我希望上面的内容可以帮助那些在解决数据中遇到困难的人。
omvjsjqw7#
看看官方的例子。X,Y和Z实际上是2d数组,numpy.meshgrid()是一种从1d x和y值获得2d x,y网格的简单方法。
http://matplotlib.sourceforge.net/mpl_examples/mplot3d/surface3d_demo.py
下面是将3元组转换为31D数组Python方法。
这是mtaplotlib delaunay三角剖分(插值),它将1d x,y,z转换为兼容的东西(?):
http://matplotlib.sourceforge.net/api/mlab_api.html#matplotlib.mlab.griddata
6tdlim6h8#
在Matlab中,我使用
delaunay
函数在x
,y
坐标上做了类似的事情(不是z
),然后用trimesh
或trisurf
绘图,使用z
作为高度。SciPy有Delaunay类,它基于与Matlab的
delaunay
函数相同的底层QHull库,所以你应该得到相同的结果。从那里开始,应该只需要几行代码就可以将这个Plotting 3D Polygons in python-matplotlib示例转换为您希望实现的内容,因为
Delaunay
为您提供了每个三角形多边形的规范。mbskvtky9#
不可能使用您的数据直接制作3D曲面。我建议你使用pykridge之类的工具来构建插值模型。这一进程将包括三个步骤:
1.使用
pykridge
训练插值模型1.使用
meshgrid
从X
和Y
构建网格1.为
Z
插值创建网格和相应的
Z
值之后,现在可以使用plot_surface
了。请注意,根据数据的大小,meshgrid
函数可以运行一段时间。解决方法是使用X
和Y
轴的np.linspace
创建均匀间隔的样本,然后应用插值来推断必要的Z
值。如果是这样,插值可能与原始Z
不同,因为X
和Y
已经改变。