亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

使用 Python 的 matplotlib 3D API 的輪廓問題

使用 Python 的 matplotlib 3D API 的輪廓問題

子衿沉夜 2023-10-11 20:14:31
我正在嘗試做一些類似于文檔中的 3D 示例的事情,但使用點云而不是光滑表面。該示例將 2D 輪廓投影到三個坐標平面中的每一個平面上。這表明我能夠在xy平面上做到這一點。當我嘗試在其他兩個平面上做同樣的事情時,我得到一個奇怪的輪廓塌陷成一條細條,或者是我在 matplotlib 內部無法企及的例外。Traceback (most recent call last):  File ".../matplotlib/backends/backend_qt5.py", line 519, in _draw_idle    self.draw()  File ".../matplotlib/backends/backend_agg.py", line 433, in draw    self.figure.draw(self.renderer)  File ".../matplotlib/artist.py", line 55, in draw_wrapper    return draw(artist, renderer, *args, **kwargs)  File ".../matplotlib/figure.py", line 1475, in draw    renderer, self, artists, self.suppressComposite)  File ".../matplotlib/image.py", line 141, in _draw_list_compositing_images    a.draw(renderer)  File ".../mpl_toolkits/mplot3d/axes3d.py", line 281, in draw    reverse=True)):  File ".../mpl_toolkits/mplot3d/axes3d.py", line 280, in <lambda>    key=lambda col: col.do_3d_projection(renderer),  File ".../mpl_toolkits/mplot3d/art3d.py", line 226, in do_3d_projection    self._segments3d]  File ".../mpl_toolkits/mplot3d/art3d.py", line 225, in <listcomp>    proj3d.proj_trans_points(points, renderer.M) for points in  File ".../mpl_toolkits/mplot3d/proj3d.py", line 188, in proj_trans_points    xs, ys, zs = zip(*points)ValueError: not enough values to unpack (expected 3, got 0)下面是該問題的一個示例。此版本有效。取消注釋函數中的一個或兩個調用,以查看奇怪的輪廓,或者更有可能是異常。ax.contour()plot()這是 matplotlib 2.2.2 和 3.1.1 的。感謝您提供的任何幫助,以獲得所有三個平面上的輪廓,例如演示。
查看完整描述

1 回答

?
慕桂英4014372

TA貢獻1871條經驗 獲得超13個贊

一位matplotlib開發人員指出,重新采樣是錯誤的。修復后,這是更正后的情節。

https://img1.sycdn.imooc.com/65269ec6000105c004880321.jpg

對于邊上看到數據的坐標平面,例如本例中的 yz 平面,等高線看起來可能有點不穩定。這是意料之中的,因為數據可以接近多值。xz平面輪廓看起來也很粗糙。我懷疑這兩個問題都可以通過單獨三角化和輪廓化每個平面來改善,而不是像這里所做的那樣偏愛 xy 平面。


下面是固定的測試腳本。唯一重要的更改是 和 。plot()resample()


import math

import sys

import matplotlib as mpl

import matplotlib.pyplot as plt

import mpl_toolkits.mplot3d

import numpy as np

import scipy.spatial


#np.random.seed(4)

numPts = 1000                                       # number of points in cloud

numGrid = 120      # number of points in meshgrid used in resample for contours

scatter = False                         # adds scatter plot to show point cloud



def main():

    (pts, f) = mkData()                                # create the point cloud

    tris = mkTris(pts)                                         # triangulate it

    plot(pts, tris, f)                                                # plot it



def plot(pts, tris, f):

    fig = plt.figure()

    ax = fig.add_subplot(111, projection="3d")


    cmap = plt.get_cmap("coolwarm")


    collec = ax.plot_trisurf(tris, pts[:, 2], cmap=cmap)

    colors = np.mean(f[tris.triangles], axis=1)

    collec.set_array(colors)

    collec.autoscale()


    (xr, yr, zr, fr, xMin, xMax, yMin, yMax, zMin, zMax) = resample(ax, tris,

       pts, f)


    ax.set_xlim(xMin, xMax)      # default always includes zero for some reason

    ax.set_ylim(yMin, yMax)

    ax.set_zlim(zMin, zMax)


    ax.contour(xr, yr, fr, 10, zdir="z", cmap=cmap, offset=zMin)

    ax.contour(fr, yr, zr, 10, zdir="x", cmap=cmap, offset=xMin)

    ax.contour(xr, fr, zr, 10, zdir="y", cmap=cmap, offset=yMax)


    if scatter:

       ax.scatter(pts[:, 0], pts[:, 1], pts[:, 2], alpha=0.1)


    ax.set_xlabel("x")

    ax.set_ylabel("y")

    ax.set_zlabel("z")

    fig.colorbar(collec, shrink=0.5, aspect=5)

    plt.show()



def mkData():

    """

    Create a random point cloud near a random plane, and define a function on

    the plane for colors and contours.

    """

    offset = 1                   # generate points near a unit square, xy-plane

    pts = 2 * np.random.rand(numPts, 3) - 1

    pts[:, 2] = offset * (2 * np.random.rand(numPts) - 1)


    x = 2 * np.ravel(pts[:, 0])

    y = 2 * np.ravel(pts[:, 1])

    f = x * np.exp(-x**2 - y**2)      # just some function for colors, contours


    width = 100                       # scale unit square to a larger rectangle

    height = 20

    pts[:, 0] *= width

    pts[:, 1] *= height


    (e1, e2, e3) =[2 * np.pi * np.random.rand() for _ in range(3)]

    (c1, s1) = (math.cos(e1), math.sin(e1))           # rotate scaled rectangle

    (c2, s2) = (math.cos(e2), math.sin(e2))

    (c3, s3) = (math.cos(e3), math.sin(e3))

    Ta2b = np.array((                     # do not have scipy.spatial.transform

        [               c1  *c2,       s2,              -s1 * c2],

        [s1 * s3 - c1 * s2 * c3,  c2 * c3, c1 *s3 + s1 * s2 * c3],

        [s1 * c3 + c1 * s2 * s3, -c2 * s3, c1 *c3 - s1 * s2 * s3]))


    pts = (Ta2b @ pts.T).T


    dist = 500                                 # translate away from the origin

    Ra2bNb = dist * (2 * np.random.rand(3, 1) - 1)


    pts += Ra2bNb.T


    return (pts, f)



def mkTris(pts):

    "Triangulate the point cloud."

    u = np.ravel(pts[:, 0])

    v = np.ravel(pts[:, 1])


    try:

        return mpl.tri.Triangulation(u, v)

    except (ValueError, RuntimeError) as ex:

        sys.exit(f"Unable to compute triangulation: {ex}.")



def resample(ax, tris, pts, f):

    "Resample the triangulation onto a regular grid for contours."

    (xMin, xMax) = ax.get_xlim()

    (yMin, yMax) = ax.get_ylim()

    (zMin, zMax) = ax.get_zlim()


    x = np.linspace(xMin, xMax, numGrid)

    y = np.linspace(yMin, yMax, numGrid)


    (xm, ym)=np.meshgrid(x, y)


    fInterp = mpl.tri.CubicTriInterpolator(tris, f)

    fm = fInterp(xm, ym)


    zInterp = mpl.tri.CubicTriInterpolator(tris, pts[:,2])

    zm = zInterp(xm, ym)


    return (xm, ym, zm, fm, xMin, xMax, yMin, yMax, zMin, zMax)


if __name__ == "__main__":

    main()



查看完整回答
反對 回復 2023-10-11
  • 1 回答
  • 0 關注
  • 138 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號