如何根据实际坐标生成matplotlib填充等高线图的数据?

时间:2016-02-09 21:33:43

标签: python arrays numpy matplotlib

我所拥有的是一组正常的坐标,如A点[1,2,3]; B点[3,6,5] ......

我想拥有的有点像这样: enter image description here 代码(由matplotlib提供)如下:

"""
.. versionadded:: 1.1.0
   This demo depends on new features added to contourf3d.
"""

from mpl_toolkits.mplot3d import axes3d
import matplotlib.pyplot as plt
from matplotlib import cm

fig = plt.figure()
ax = fig.gca(projection='3d')
X, Y, Z = axes3d.get_test_data(1.0)
print X
print(Y)
print(Z)
ax.plot_surface(X, Y, Z, rstride=8, cstride=8, alpha=0.3)
cset = ax.contourf(X, Y, Z, zdir='z', offset=-100, cmap=cm.coolwarm)
cset = ax.contourf(X, Y, Z, zdir='x', offset=-40, cmap=cm.coolwarm)
cset = ax.contourf(X, Y, Z, zdir='y', offset=40, cmap=cm.coolwarm)

ax.set_xlabel('X')
ax.set_xlim(-40, 40)
ax.set_ylabel('Y')
ax.set_ylim(-40, 40)
ax.set_zlabel('Z')
ax.set_zlim(-100, 100)

plt.show()

我想了解这些X,Y和Z是如何工作的。 所以印刷的陈述告诉我:

[[-30. -20. -10.   0.  10.  20.]
 [-30. -20. -10.   0.  10.  20.]
 [-30. -20. -10.   0.  10.  20.]
 [-30. -20. -10.   0.  10.  20.]
 [-30. -20. -10.   0.  10.  20.]
 [-30. -20. -10.   0.  10.  20.]]
[[-30. -30. -30. -30. -30. -30.]
 [-20. -20. -20. -20. -20. -20.]
 [-10. -10. -10. -10. -10. -10.]
 [  0.   0.   0.   0.   0.   0.]
 [ 10.  10.  10.  10.  10.  10.]
 [ 20.  20.  20.  20.  20.  20.]]
[[ -9.82064017e-03  -1.19639890e-01  -5.36188786e-01  -8.84025856e-01
   -5.36188786e-01  -1.19639890e-01]
 [ -1.19639843e-01  -1.45751201e+00  -6.53211598e+00  -1.07696384e+01
   -6.53211503e+00  -1.45751094e+00]
 [ -5.35172034e-01  -6.52729956e+00  -2.92602828e+01  -4.82376751e+01
   -2.92393221e+01  -6.50361544e+00]
 [ -4.73838989e-01  -8.82629001e+00  -4.23628013e+01  -6.80792672e+01
   -3.39066568e+01   7.28564728e-01]
 [  2.49470498e+00   7.82740289e+00   1.43454530e+01   3.66947009e+01
    7.68283796e+01   7.84287606e+01]
 [  2.90546977e-01   4.85837411e-01  -6.28741676e-01   7.28564728e-01
    7.82740289e+00   1.00406921e+01]]

据我所知,对于X处的任何一点,第一行[[-30. -20. -10. 0. 10. 20.],给定常数Y为-30([[-30. -30. -30. -30. -30. -30.]),高度(Z)为[[ -9.82064017e-03 -1.19639890e-01 -5.36188786e-01 -8.84025856e-01 -5.36188786e-01 -1.19639890e-01]那个&#39}好的,但在现实生活中的数据,更有可能,你有点像:

X = [1, 2, 3]
Y = [4, 5, 6]
Z = [10, 9, 10]

所以它不是真的像所有东西都被定义,而不是你有一些点,即a = [1,4,10],b = [2,5,9]和c = [3,6] ,10]。它不是真的像你有a1 = [1,4,10],a2 = [2,4,10],a3 = [3,4,10]等等。因此,考虑到通常出现的数据,如何构建3D等高线图?

我也知道我需要一个2D numpy数组,这里解释了如何得到一个:Make 2D Numpy array from coordinates 我还不了解的是如何转换/使用一些真实的坐标数据。

如果我将点作为散点图绘制,请参阅以下内容:

enter image description here

我想在散射上创建一个表面,因为它们肯定会形成一些峰和平原的浮雕。

1 个答案:

答案 0 :(得分:2)

如果您的心脏设置在3D曲面图上,您有两个主要选项:

  1. 直接绘制不规则采样数据

  2. 在常规网格上重新采样数据

  3. 如果你选择选项1,你可以使用plot_trisurfDelaunay triangulation使用np.histogram2d来推断应该用线连接哪些点以创建曲面。我的猜测是,这可能看起来很混乱,因为它本身并不适用于任何类型的平滑或插值。如果你有很多,那么渲染也可能需要很长时间。

    如果您选择选项2,那么您在重新采样数据方面有多种选择。最简单的选择之一是计算加权的2D直方图,例如,使用plot_surface

    H, xedges, yedges = np.histogram2d(x, y, bins=[nx, ny], weights=z)
    

    H将是(nx, ny)二维数组,其中X[i, j]给出xedges[i:i+1]和{{1}指定的二进制位内所有点的平均z值(有关完整详细信息,请参阅文档)。要将其绘制为3D表面,您可以使用here

    yedges[i:i+1]

    在选择直方图区域大小方面,需要在使直方图看起来平滑并在数据集中捕获结构之间进行权衡。

    除了计算直方图外,您还可以使用插值平滑。这些都涉及为您的数据拟合某些功能,然后可以在常规网格上进行评估。在插值的情况下,该函数被约束为精确地通过所有输入数据点,而通过平滑,该约束被放宽以便使噪声平滑。 Scipy实现了许多不同的插值和平滑方法,因此我建议您查看文档scipy.interpolate.SmoothBivariateSpline

    一种选择是双三次样条平滑,例如enter image description here

    from mpl_toolkits import mplot3d
    
    fig, ax = plt.subplots(1, 1, subplot_kw={'projection':'3d'})
    xcentres = (xedges[1:] + xedges[:-1]) / 2
    ycentres = (yedges[1:] + yedges[:-1]) / 2
    xc, yc = np.ix_(xcentres, ycentres)
    ax.plot_surface(xc, yc, H, cmap='Blues', alpha=0.5)
    

    然后您可以使用from scipy.interpolate import SmoothBivariateSpline # play around with the s= parameter to control the degree of smoothing spl = SmoothBivariateSpline(x, y, z) # coordinates to evaluate the spline fit at xeval = np.linspace(xmin, xmax, nx) yeval = np.linspace(ymin, ymax, ny) # evaluate the spline fit H = spl(xeval, yeval, grid=True)

    像以前一样绘制此图
    plt_surface

    enter image description here

    就我个人而言,我并不是3D绘图的忠实粉丝 - 每当我看到3D绘图时,几乎总有一种更清晰的方式来表示2D中的数据。例如,您可以将不规则采样的x,y,z数据绘制为散点图,使用标记大小和/或颜色来表示z轴,例如:

    fig, ax = plt.subplots(1, 1, subplot_kw={'projection':'3d'})
    xe, ye = np.ix_(xeval, yeval)
    ax.plot_surface(xe, ye, H, cmap='Blues', alpha=0.5)
    ax.scatter3D(x, y, z, 'ob')
    

    matplotlib gallery

    您还可以将定期采样的2D数据表示为伪彩色图(plt.scatter(x, y, z, z, cmap='Blues') ),图像(plt.pcolormesh)或等高线图(plt.imshow / plt.contour)。< / p>

    请查看http://domain.com/xxxx/yyyy/zzzz?qqqq以获取更多示例。