/ / Matplotlib като matlab's trisurf - питън, matlab, matplotlib, 3d, окото

Matplotlib като trisurf matlab - питън, matlab, matplotlib, 3d, окото

За да направя дълга история кратка, бих искал да начертая триъгълни триъгълни отвори в питън. Матплотбиб изглежда идеален кандидат, но ще отида с 3D изображение, което може да направи онова, което ще опиша.

Да предположим, че имам триъгълна мрежа, дефинирана от X, Y,и З, 3D координатите на точков облак, всеки вектор с дължина n и UVW, матрица 2D m-x-3, в която всеки ред е трипътен индекс в точката на облака. Този триплет представлява индивидуален триъгълник. С други думи, имам триъгълници над n точки. В Matlab, за генериране на 3D парцел, просто правя:

trisurf(UVW, X, Y, Z)

Някой има ли опит с това? По-конкретно, може ли трюфели да бъдат обучени да работят?

Отговори:

5 за отговор № 1

В зависимост от вашите нужди за изпълнение, Mayavi вероятно ще бъде най-подходящ за това - според коментара на Дейвис.

Въпреки това, matplotlib идва с plot_trisurf към която можете да преминете перфектно UVW, X, Y , Z както описваш.

Пример с торова мрежа:

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

R = 1.
r = 0.8
n = 50
m = 50

def torus_triangles(n, m):
""" Returns triangles to mesh a (n, m) torus """
tri = []
for i in range(n):
for j in range(m):
a = i + j*(n)
b = ((i+1) % n) + j*n
d = i + ((j+1) % m) * n
c = ((i+1) % n) + ((j+1) % m) * n
tri += [[a, b, d], [b, c, d]]
return np.array(tri, dtype=np.int32)

theta0 = np.linspace(0, (2*np.pi), n, endpoint=False)
phi0 = np.linspace(0, (2*np.pi), m, endpoint=False)
theta, phi = np.meshgrid(theta0, phi0)

x = (R + r * np.sin(phi)) * np.cos(theta)
y = (R + r * np.sin(phi)) * np.sin(theta)
z = r * np.cos(phi)

triangles = torus_triangles(n , m)
triang = mtri.Triangulation(x.ravel(), y.ravel(), triangles)

fig = plt.figure()
ax = fig.add_subplot(111, projection="3d")
ax.plot_trisurf(triang, z.ravel(), lw=0.2, edgecolor="black", color="grey",
alpha=0.5)

plt.show()

въведете описанието на изображението тук


1 за отговор № 2

Plotly има отворен код trisurf Python, който е по-близо до MATLAB's trisurf ().

Python код и примери тук:

https://plot.ly/python/tri-surf/

python trisurf


1 за отговор № 3

Аз също търсех решение на този проблем и тази дискусия ми помогна да успея. Ето как работи:

  1. Решението на много подобен проблем вече беше дадено като връзка в коментара на GBy (виж по-горе: Оцветяване на повърхността на сфера с набор от скаларни стойности в matplotlib)

  2. Прехвърлянето на знанието към проблема тук води до създаването на допълнителен масив, съдържащ амплитудите и задаването му на "основния ScalarMappable through set_array метод "съответният код на Python изглежда така:

    from mpl_toolkits.mplot3d import Axes3D
    from matplotlib import cm
    from matplotlib import pyplot as plt
    import numpy as np
    
    fig = plt.figure()
    ax = fig.gca(projection="3d")
    colors = np.mean(CorticalImage[Face], axis=1)
    collec = ax.plot_trisurf(Xcoordinates, Ycoordinates, Zcoordinates, triangles=Face, cmap=cm.jet, linewidth=0.2)
    collec.set_array(colors)
    collec.autoscale()
    ax.view_init(30, 0)
    cbar = fig.colorbar(collec)
    

Масивите Xcoordinates, Ycoordinates, Zcoordinates съдържат координатите X, Y и Z на мрежовите възли. При проверка на формата им с напр. Xcoordinates.shape това трябва да изглежда така (750,), където 750 е броят на мрежовите възли. Матрицата Face е същата като матрицата UVW в оригиналния въпрос, зададен от Лари. Това е "2D m-x-3 матрица, в която всеки ред е трикратно на индекси в точката облак". Ако проверите формата на матрицата Face тя трябва да е нещо като (1496, 3), където 1496 е броят на триъгълниците в окото и 3 е броят на възлите в един триъгълник. Накрая, масивът CorticalImage съдържа амплитудите за всеки възел ви това са стойностите, които искаме да използваме за цветовете на окото (а не на стойностите Z). Формата на този масив трябва да бъде като формите на координатните решетки, т.е. (750,).

ВАЖНО !!! Можете да видите, че броят на възлите и броят на триъгълниците не са равни. Това почти винаги е така. Освен това, амплитудите обикновено се дават за възлите, а не за триъгълниците. Следователно, амплитудите трябва да бъдат изчислени за триъгълниците, за да се получат правилните цветове в участъка. Това се прави в реда colors = np.mean(CorticalImage[Face], axis=1).


1 за отговор № 4

Мисъл за изчерпателност Аз бих добавил a mayavi пример тук, използвайки окото от отговора на GBy.

import numpy as np
from mayavi import mlab
from tvtk.api import tvtk

R = 1.
r = 0.8
n = 50
m = 50

def torus_triangles(n, m):
""" Returns triangles to mesh a (n, m) torus """
tri = []
for i in range(n):
for j in range(m):
a = i + j*(n)
b = ((i+1) % n) + j*n
d = i + ((j+1) % m) * n
c = ((i+1) % n) + ((j+1) % m) * n
tri += [[a, b, d], [b, c, d]]
return np.array(tri, dtype=np.int32)

theta0 = np.linspace(0, (2*np.pi), n, endpoint=False)
phi0 = np.linspace(0, (2*np.pi), m, endpoint=False)
theta, phi = np.meshgrid(theta0, phi0)

x = (R + r * np.sin(phi)) * np.cos(theta)
y = (R + r * np.sin(phi)) * np.sin(theta)
z = r * np.cos(phi)

triangles = torus_triangles(n , m)

mesh = mlab.triangular_mesh(x,y,z, triangles, representation="wireframe",color=(0,0,1) )

mlab.show()

Добива

въведете описанието на изображението тук