用 matplotlib 表示体素

2024-02-27

在Python中,给定一个N_1 x N_2 x N_3包含 0 或 1 的矩阵,我会寻找一种方法将 3D 数据显示为N_1 x N_2 x N_3体积与 1s 位置处的体积像素(体素)。

例如,如果 1s 的坐标是[[1, 1, 1], [4, 1, 2], [3, 4, 1]],所需的输出将如下所示

看来mplot3Dmatplotlib 模块有可能实现这一点,但我还没有找到这种绘图的任何例子。有人知道解决这个问题的简单解决方案吗?

预先非常感谢您的帮助。


A、使用voxels

从 matplotlib 2.1 开始,有一个Axes3D.voxels https://matplotlib.org/api/_as_gen/mpl_toolkits.mplot3d.axes3d.Axes3D.html#mpl_toolkits.mplot3d.axes3d.Axes3D.voxels功能可用,这几乎可以满足这里的要求。然而,它不太容易定制为不同的尺寸、位置或颜色。

from mpl_toolkits.mplot3d import Axes3D
import numpy as np
import matplotlib.pyplot as plt
N1 = 10
N2 = 10
N3 = 10
ma = np.random.choice([0,1], size=(N1,N2,N3), p=[0.99, 0.01])

fig = plt.figure()
ax = fig.gca(projection='3d')
ax.set_aspect('equal')

ax.voxels(ma, edgecolor="k")

plt.show()

要将体素放置在不同的位置,请参见如何使用 Matplotlib 缩放体素尺寸? https://stackoverflow.com/a/56753251/4124317.

B、使用Poly3DCollection

手动创建体素可以使过程更加透明,并允许对体素的大小、位置和颜色进行任何类型的自定义。另一个优点是,这里我们创建一个单独的 Poly3DCollection,而不是多个,使得该解决方案比内置更快voxels.

from mpl_toolkits.mplot3d import Axes3D
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d.art3d import Poly3DCollection

def cuboid_data(o, size=(1,1,1)):
    X = [[[0, 1, 0], [0, 0, 0], [1, 0, 0], [1, 1, 0]],
         [[0, 0, 0], [0, 0, 1], [1, 0, 1], [1, 0, 0]],
         [[1, 0, 1], [1, 0, 0], [1, 1, 0], [1, 1, 1]],
         [[0, 0, 1], [0, 0, 0], [0, 1, 0], [0, 1, 1]],
         [[0, 1, 0], [0, 1, 1], [1, 1, 1], [1, 1, 0]],
         [[0, 1, 1], [0, 0, 1], [1, 0, 1], [1, 1, 1]]]
    X = np.array(X).astype(float)
    for i in range(3):
        X[:,:,i] *= size[i]
    X += np.array(o)
    return X

def plotCubeAt(positions,sizes=None,colors=None, **kwargs):
    if not isinstance(colors,(list,np.ndarray)): colors=["C0"]*len(positions)
    if not isinstance(sizes,(list,np.ndarray)): sizes=[(1,1,1)]*len(positions)
    g = []
    for p,s,c in zip(positions,sizes,colors):
        g.append( cuboid_data(p, size=s) )
    return Poly3DCollection(np.concatenate(g),  
                            facecolors=np.repeat(colors,6, axis=0), **kwargs)

N1 = 10
N2 = 10
N3 = 10
ma = np.random.choice([0,1], size=(N1,N2,N3), p=[0.99, 0.01])
x,y,z = np.indices((N1,N2,N3))-.5
positions = np.c_[x[ma==1],y[ma==1],z[ma==1]]
colors= np.random.rand(len(positions),3)

fig = plt.figure()
ax = fig.gca(projection='3d')
ax.set_aspect('equal')

pc = plotCubeAt(positions, colors=colors,edgecolor="k")
ax.add_collection3d(pc)

ax.set_xlim([0,10])
ax.set_ylim([0,10])
ax.set_zlim([0,10])
#plotMatrix(ax, ma)
#ax.voxels(ma, edgecolor="k")

plt.show()

C、使用plot_surface

改编代码来自这个答案 https://stackoverflow.com/a/40412894/4124317(部分基于这个答案 https://stackoverflow.com/a/35978146/4124317),我们可以轻松地将长方体绘制为曲面图 http://matplotlib.org/mpl_toolkits/mplot3d/tutorial.html#surface-plots.

然后可以迭代输入数组并找到一个1在与数组索引对应的位置绘制一个长方体。

这样做的优点是您可以在表面上获得漂亮的阴影,从而增加 3D 效果。缺点可能是立方体在某些情况下可能不具有物理行为,例如它们可能在某些视角下重叠。

from mpl_toolkits.mplot3d import Axes3D
import numpy as np
import matplotlib.pyplot as plt

def cuboid_data(pos, size=(1,1,1)):
    # code taken from
    # https://stackoverflow.com/a/35978146/4124317
    # suppose axis direction: x: to left; y: to inside; z: to upper
    # get the (left, outside, bottom) point
    o = [a - b / 2 for a, b in zip(pos, size)]
    # get the length, width, and height
    l, w, h = size
    x = [[o[0], o[0] + l, o[0] + l, o[0], o[0]],  
         [o[0], o[0] + l, o[0] + l, o[0], o[0]],  
         [o[0], o[0] + l, o[0] + l, o[0], o[0]],  
         [o[0], o[0] + l, o[0] + l, o[0], o[0]]]  
    y = [[o[1], o[1], o[1] + w, o[1] + w, o[1]],  
         [o[1], o[1], o[1] + w, o[1] + w, o[1]],  
         [o[1], o[1], o[1], o[1], o[1]],          
         [o[1] + w, o[1] + w, o[1] + w, o[1] + w, o[1] + w]]   
    z = [[o[2], o[2], o[2], o[2], o[2]],                       
         [o[2] + h, o[2] + h, o[2] + h, o[2] + h, o[2] + h],   
         [o[2], o[2], o[2] + h, o[2] + h, o[2]],               
         [o[2], o[2], o[2] + h, o[2] + h, o[2]]]               
    return np.array(x), np.array(y), np.array(z)

def plotCubeAt(pos=(0,0,0),ax=None):
    # Plotting a cube element at position pos
    if ax !=None:
        X, Y, Z = cuboid_data( pos )
        ax.plot_surface(X, Y, Z, color='b', rstride=1, cstride=1, alpha=1)

def plotMatrix(ax, matrix):
    # plot a Matrix 
    for i in range(matrix.shape[0]):
        for j in range(matrix.shape[1]):
            for k in range(matrix.shape[2]):
                if matrix[i,j,k] == 1:
                    # to have the 
                    plotCubeAt(pos=(i-0.5,j-0.5,k-0.5), ax=ax)            

N1 = 10
N2 = 10
N3 = 10
ma = np.random.choice([0,1], size=(N1,N2,N3), p=[0.99, 0.01])

fig = plt.figure()
ax = fig.gca(projection='3d')
ax.set_aspect('equal')

plotMatrix(ax, ma)

plt.show()
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

用 matplotlib 表示体素 的相关文章

  • Twisted 的 Deferred 和 JavaScript 中的 Promise 一样吗?

    我开始在一个需要异步编程的项目中使用 Twisted 并且文档非常好 所以我的问题是 Twisted 中的 Deferred 与 Javascript 中的 Promise 相同吗 如果不是 有什么区别 你的问题的答案是Yes and No
  • opencv水印周围的轮廓

    我想在图像中的水印周围画一个框 我已经提取了水印并找到了轮廓 但是 不会在水印周围绘制轮廓 轮廓是在我的整个图像上绘制的 请帮我提供正确的代码 轮廓坐标的输出为 array 0 0 0 634 450 634 450 0 dtype int
  • 如何检查python xlrd库中的excel文件是否有效

    有什么办法与xlrd库来检查您使用的文件是否是有效的 Excel 文件 我知道还有其他库可以检查文件头 我可以使用文件扩展名检查 但为了多平台性我想知道是否有任何我可以使用的功能xlrd库本身在尝试打开文件时可能会返回类似 false 的内
  • sklearn 中的 pca.inverse_transform

    将我的数据拟合后 X 我的数据 pca PCA n components 1 pca fit X X pca pca fit transform X 现在 X pca 具有一维 当我根据定义执行逆变换时 它不是应该返回原始数据 即 X 二维
  • 搜索多个字段

    我想我没有正确理解 django haystack 我有一个包含多个字段的数据模型 我希望搜索其中两个字段 class UserProfile models Model user models ForeignKey User unique
  • Emacs 24.x 上的 IPython 支持

    我对 IPython 与 Emacs 的集成感到困惑 从 Emacs 24 开始 Emacs 附带了自己的python el 该文件是否支持 IPython 还是仅支持 Python 另外 维基百科 http emacswiki org e
  • 如果在等待“read -s”时中断,在子进程中运行 bash 会破坏 tty 的标准输出吗?

    正如 Bakuriu 在评论中指出的那样 这基本上与BASH 输入期间按 Ctrl C 会中断当前终端 https stackoverflow com questions 31808863 bash ctrlc during input b
  • Django send_mail SMTPSenderRefused 530 与 gmail

    一段时间以来 我一直在尝试使用 Django 从我正在开发的网站接收电子邮件 现在 我还没有部署它 并且我正在使用Django开发服务器 我不知道这是否会影响它 这是我的 settings py 配置 EMAIL BACKEND djang
  • Python新式类和__subclasses__函数

    有人可以向我解释为什么这有效 在 Python 2 5 中 class Foo object pass class Bar Foo pass print Foo subclasses 但这不是 class Foo pass class Ba
  • .pyx 文件出现未知文件类型错误

    我正在尝试构建一个包含 pyx 文件的 Python 包 pyregion 但在构建过程中出现错误 检查以下输出 python setup py build running build running build py creating b
  • 用 python 编写的数学语法检查器

    我需要的只是使用 python 检查字符串是否是有效的数学表达式 为了简单起见 假设我只需要 运算符 也作为一元 带有数字和嵌套括号 为了完整性 我还添加了简单的变量名称 所以我可以这样测试 test 3 2 1 valid test 3
  • Jython 和 SAX 解析器:允许的实体不超过 64000 个?

    我做了一个简单的测试xml saxJython 中的解析器在处理大型 XML 文件 800 MB 时遇到以下错误 Traceback most recent call last File src project xmltools py li
  • ANTLR 获取并拆分词法分析器内容

    首先 对我的英语感到抱歉 我还在学习 我为我的框架编写 Python 模块 用于解析 CSS 文件 我尝试了 regex ply python 词法分析器和解析器 但我发现自己在 ANTLR 中 第一次尝试 我需要解析 CSS 文件中的注释
  • 使用“默认”环境变量启动新的子进程

    我正在编写一个构建脚本来解析依赖的共享库 及其共享库等 这些共享库在正常情况下是不存在的PATH环境变量 为了使构建过程正常工作 让编译器找到这些库 PATH已更改为包含这些库的目录 构建过程是这样的 加载器脚本 更改 PATH gt 基于
  • 从 NumPy 数组到 Mat 的 C++ 转换 (OpenCV)

    我正在围绕 ArUco 增强现实库 基于 OpenCV 编写一个薄包装器 我试图构建的界面非常简单 Python 将图像传递给 C 代码 C 代码检测标记并将其位置和其他信息作为字典元组返回给 Python 但是 我不知道如何在 Pytho
  • 动态过滤 pandas 数据框

    我正在尝试使用三列的阈值来过滤 pandas 数据框 import pandas as pd df pd DataFrame A 6 2 10 5 3 B 2 5 3 2 6 C 5 2 1 8 2 df df loc df A gt 0
  • 当数据库不是 Django 模型时,是否可以使用数据库中的表?

    是否可以从应用程序数据库中的表获取查询集 该表不是应用程序中的模型 如果我有一个不是名为 cartable 的模型的表 从概念上讲 我想这样做 myqueryset cartable objects all 有没有相对简单的方法来做到这一点
  • Python SSL X509:KEY_VALUES_MISMATCH

    Python HTTPS server from http server import HTTPServer SimpleHTTPRequestHandler import ssl https stackoverflow com a 408
  • TKinter 中的禁用/启用按钮

    我正在尝试制作一个像开关一样的按钮 所以如果我单击禁用按钮 它将禁用 按钮 有效 如果我再次按下它 它将再次启用它 我尝试了 if else 之类的东西 但没有成功 这是一个例子 from tkinter import fenster Tk
  • Apache Beam Pipeline 写表后查询表

    我有一个 Apache Beam Dataflow 管道 它将结果写入 BigQuery 表 然后我想查询该表以获取管道的单独部分 但是 我似乎无法弄清楚如何正确设置此管道依赖性 我编写的新表 然后想要查询 与一个单独的表连接以进行某些过滤

随机推荐