使用 Python 的 matplotlib 3D API 绘制轮廓的问题

2023-12-02

我正在尝试做类似的事情this文档中的 3D 示例,但使用点云而不是光滑表面。该示例将 2D 轮廓投影到三个坐标平面中的每一个上。这表明我能够在 xy 平面上做到这一点。

2D contour successfully added to xy-plane.

当我尝试在其他两个平面上做同样的事情时,我得到的要么是一个奇怪的轮廓塌陷成一条细条,

2D contour on yz-plane collapsed into a thin strip.

或者是我无法触及的异常绘图库.

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() in the plot()函数可以看到奇怪的轮廓,或更可能的是异常。

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
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, xMin, yMin, zMin, zMax) = resample(ax, tris, f)
    ax.set_zlim(zMin, zMax)      # default always includes zero for some reason

    #
    # Uncomment one or both of these lines to see the problem.
    #
    ax.contour(xr, yr, zr, 10, zdir="z", cmap=cmap, offset=zMin)
    #ax.contour(xr, yr, zr, 10, zdir="x", cmap=cmap, offset=xMin)
    #ax.contour(xr, yr, zr, 10, zdir="y", cmap=cmap, offset=yMin)

    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, f):         # resample triangulation onto a regular grid
    (xMin, xMax) = ax.get_xlim()
    (yMin, yMax) = ax.get_ylim()
    (zMin, zMax) = ax.get_zlim()

    x = np.linspace(xMin, xMax, 30)
    y = np.linspace(yMin, yMax, 30)

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

    interp = mpl.tri.triinterpolate.LinearTriInterpolator(tris, f)
    zm = interp(xm, ym)

    return (xm, ym, zm, xMin, yMin, zMin, zMax)

if __name__ == "__main__":
    main()

这是与绘图库2.2.2 和 3.1.1。感谢您提供的任何帮助来获取所有三个平面上的轮廓,例如演示。

Jim


A 绘图库开发者指出重采样是错误的。修复后,这是更正后的图。

enter image description here

对于从侧面查看数据的坐标平面,例如yz- 在这种情况下是平面,轮廓可能看起来有点不稳定。这是预期的,因为数据可以接近多值。这xz- 平面轮廓看起来也很参差不齐。我怀疑这两个问题可以通过单独对每个平面进行三角测量和轮廓绘制来改善,而不是偏向于xy- 飞机如这里所做的那样。

这是固定的测试脚本。唯一重要的变化是plot() and 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()
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 Python 的 matplotlib 3D API 绘制轮廓的问题 的相关文章

  • 将字符串转换为带有毫秒和时区的日期时间 - Python

    我有以下 python 片段 from datetime import datetime timestamp 05 Jan 2015 17 47 59 000 0800 datetime object datetime strptime t
  • Python PAM 模块的安全问题?

    我有兴趣编写一个 PAM 模块 该模块将利用流行的 Unix 登录身份验证机制 我过去的大部分编程经验都是使用 Python 进行的 并且我正在交互的系统已经有一个 Python API 我用谷歌搜索发现pam python http pa
  • Pycharm Python 控制台不打印输出

    我有一个从 Pycharm python 控制台调用的函数 但没有显示输出 In 2 def problem1 6 for i in range 1 101 2 print i end In 3 problem1 6 In 4 另一方面 像
  • Flask 和 uWSGI - 无法加载应用程序 0 (mountpoint='')(找不到可调用或导入错误)

    当我尝试使用 uWSGI 启动 Flask 时 出现以下错误 我是这样开始的 gt cd gt root localhost uwsgi socket 127 0 0 1 6000 file path to folder run py ca
  • 如何等到 Excel 计算公式后再继续 win32com

    我有一个 win32com Python 脚本 它将多个 Excel 文件合并到电子表格中并将其另存为 PDF 现在的工作原理是输出几乎都是 NAME 因为文件是在计算 Excel 文件内容之前输出的 这可能需要一分钟 如何强制工作簿计算值
  • 安装后 Anaconda 提示损坏

    我刚刚安装张量流GPU创建单独的后环境按照以下指示here https github com antoniosehk keras tensorflow windows installation 但是 安装后当我关闭提示窗口并打开新航站楼弹出
  • NameError:名称“urllib”未定义”

    CODE import networkx as net from urllib request import urlopen def read lj friends g name fetch the friend list from Liv
  • feedparser 在脚本运行期间失败,但无法在交互式 python 控制台中重现

    当我运行 eclipse 或在 iPython 中运行脚本时 它失败了 ascii codec can t decode byte 0xe2 in position 32 ordinal not in range 128 我不知道为什么 但
  • Abaqus 将曲面转化为集合

    我一直试图在模型中找到两个表面的中心 参见照片 但未能成功 它们是元素表面 面 查询中没有选项可以查找元素表面的中心 只能查找元素集的中心 找到节点集的中心也很好 但是我的节点集没有出现在工具 gt 查询 gt 质量属性选项中 而且我找不到
  • 如何将交互式 matplotlib 图形插入 tkinter 画布

    我正在尝试将交互式 matplotlib 图形 具有滑块 重置按钮和单选按钮的图形 放入 tkinter Canvas 中 我已成功添加非交互式图表 但当它变为交互式时找不到问题 我尝试将所有内容更改为使用 matplotlib Figur
  • 表达式中的 Python 'in' 关键字与 for 循环中的比较 [重复]

    这个问题在这里已经有答案了 我明白什么是in运算符在此代码中执行的操作 some list 1 2 3 4 5 print 2 in some list 我也明白i将采用此代码中列表的每个值 for i in 1 2 3 4 5 print
  • 如何将 numpy.matrix 提高到非整数幂?

    The 运算符为numpy matrix不支持非整数幂 gt gt gt m matrix 1 0 0 5 0 5 gt gt gt m 2 5 TypeError exponent must be an integer 我想要的是 oct
  • Python:尝试检查有效的电话号码

    我正在尝试编写一个接受以下格式的电话号码的程序XXX XXX XXXX并将条目中的任何字母翻译为其相应的数字 现在我有了这个 如果启动不正确 它将允许您重新输入正确的数字 然后它会翻译输入的原始数字 我该如何解决 def main phon
  • Python - 按月对日期进行分组

    这是一个简单的问题 起初我认为很简单而忽略了它 一个小时过去了 我不太确定 所以 我有一个Python列表datetime对象 我想用图表来表示它们 x 值是年份和月份 y 值是此列表中本月发生的日期对象的数量 也许一个例子可以更好地证明这
  • Numpy 优化

    我有一个根据条件分配值的函数 我的数据集大小通常在 30 50k 范围内 我不确定这是否是使用 numpy 的正确方法 但是当数字超过 5k 时 它会变得非常慢 有没有更好的方法让它更快 import numpy as np N 5000
  • 如何改变Python中特定打印字母的颜色?

    我正在尝试做一个简短的测验 并且想将错误答案显示为红色 欢迎来到我的测验 您想开始吗 是的 祝你好运 法国的首都是哪里 法国 随机答案不正确的答案 我正在尝试将其显示为红色 我的代码是 print Welcome to my Quiz be
  • 如何将 PIL 图像转换为 NumPy 数组?

    如何转换 PILImage来回转换为 NumPy 数组 这样我就可以比 PIL 进行更快的像素级转换PixelAccess允许 我可以通过以下方式将其转换为 NumPy 数组 pic Image open foo jpg pix numpy
  • 检查所有值是否作为字典中的键存在

    我有一个值列表和一本字典 我想确保列表中的每个值都作为字典中的键存在 目前我正在使用两组来确定字典中是否存在任何值 unmapped set foo set bar keys 有没有更Pythonic的方法来测试这个 感觉有点像黑客 您的方
  • VSCode:调试配置中的 Python 路径无效

    对 Python 和 VSCode 以及 stackoverflow 非常陌生 直到最近 我已经使用了大约 3 个月 一切都很好 当尝试在调试器中运行任何基本的 Python 程序时 弹出窗口The Python path in your
  • 使用基于正则表达式的部分匹配来选择 Pandas 数据帧的子数据帧

    我有一个 Pandas 数据框 它有两列 一列 进程参数 列 包含字符串 另一列 值 列 包含相应的浮点值 我需要过滤出部分匹配列 过程参数 中的一组键的子数据帧 并提取与这些键匹配的数据帧的两列 df pd DataFrame Proce

随机推荐