2016-06-17 5 views
3

Мне ничего не удалось найти, может быть, потому, что у меня нет нужной номенклатуры (т.е. я точно не знаю, как ее попросить), но в любом случае я имеют трехмерную матрицу «a». Я хотел бы определить и построить 2D-поверхность, где a = 0. Чтобы сделать очевидным, данные представляют собой плавающие данные двойной точности, плавно изменяющиеся по пространству 3D. Весьма вероятно, что поверхность a = 0 будет «нитью» между точками массива и не будет точно лежать на любом из них. Поэтому мне нужно что-то, что можно интерполировать, чтобы найти поверхность a = 0 и зарисовать ее. У matplotlib есть готовая рутина для этого?matplotlib 2D-фрагмент 3D-данных

+0

Это похоже больше NumPy или SciPy вещи – kilojoules

+2

я считаю, вы хотите объем слайсер. Ни numpy, scipy, ни matplotlib (насколько я знаю), по умолчанию, готовы сделать это. Вы можете рассчитать фрагменты между слоями, но вам нужно будет создать код для этого (я могу попробовать представить решение, если это вам приемлемо). Библиотека ближе к matplotlib, которая делает это Mayavi (я думаю, что она доступна только в Python 2.x). Вы также можете рассмотреть pyQtGraph, VTK или Vispy. – armatita

+0

@armatita Спасибо за ответ. По крайней мере, теперь я точно знаю, что я не просил ничего тривиального! Если вы хотите создать код, который может выполнять обрезку тома, я обязательно буду заинтересован в этом! Благодарю. –

ответ

2

Чтобы определить и построить 2D-поверхность, где a = 0, вам просто нужно подмножество данных, где a=0 и график (показано ниже). Если вы ищете проекцию данных на эту плоскость, то это немного сложнее.

threeD = np.array([(x,y,z) for x in [0,1] for y in [1,2] for z in [5,6]]) 
twoD = np.array([(y,z) for (x,y,z) in threeD if x==0]) 
y,z = zip(*twoD) 
plt.plot(y,z, 'o') 
plt.xlim(0,3) 
plt.ylim(0,7) 

enter image description here

+0

Я думаю, что мой вопрос был недостаточно ясным. Редактирование. –

0

Операция объем разрезание обычно опирается на понятие интерполяции и наиболее характерными являются: Nearest neighbor, Linear и Cubic. Обратите внимание, что эти методы адаптируются к дополнительному числу измерений (см., Например, Bilinear или Trilinear).

В этом случае вы говорите, что у вас есть том, из которого вы можете извлекать фрагменты в X, Y, Z (или гибрид, но не рассматривайте этот случай со своей новой цельной проблемы и только путают).

Итак, рассматривая, например, срез X = 5 и X = 6, вы хотите знать, как получить X = 5.5. Посмотрите на пример:

def linear_interpolation(p1, p2, x0): 
    """ 
    Function that receives as arguments the coordinates of two points (x,y) 
    and returns the linear interpolation of a y0 in a given x0 position. This is the 
    equivalent to obtaining y0 = y1 + (y2 - y1)*((x0-x1)/(x2-x1)). 
    Look into https://en.wikipedia.org/wiki/Linear_interpolation for more 
    information. 

    Parameters 
    ---------- 
    p1  : tuple (floats) 
     Tuple (x,y) of a first point in a line. 
    p2  : tuple (floats) 
     Tuple (x,y) of a second point in a line. 
    x0  : float 
     X coordinate on which you want to interpolate a y0. 

    Return float (interpolated y0 value) 
    """ 
    return p1[1] + (p2[1] - p1[1]) * ((x0 - p1[0])/(p2[0] - p1[0])) 

X, Y, Z = np.meshgrid(range(10), range(10), range(10)) 
vol = np.sqrt((X-5)**2 + (Y-5)**2 + (Z-5)**2) 

Slice5dot5 = linear_interpolation((Y[5, :, :], vol[5, :, :]), (Y[6, :, :], vol[6, :, :]), 5.5) 

f, (ax1, ax2, ax3) = plt.subplots(1, 3, sharey=True) 
ax1.imshow(vol[5, :, :], interpolation='nearest', origin='lower', vmin=vol.min(), vmax=vol.max()) 
ax1.set_title("vol[5, :, :]") 
ax2.imshow(Slice5dot5, interpolation='nearest', origin='lower', vmin=vol.min(), vmax=vol.max()) 
ax2.set_title("vol[5.5, :, :]") 
ax3.imshow(vol[6, :, :], interpolation='nearest', origin='lower', vmin=vol.min(), vmax=vol.max()) 
ax3.set_title("vol[6, :, :]") 
plt.show() 

Функция появляется документально (его часть старого проекта я сделал), который будет использоваться с номерами, но он будет работать так же хорошо с Numpy 2D ломтиками (и это будет намного быстрее, чем зацикливание всех этих ячеек).

Результат был таков:

Volume slicing matplotlib

Вы заметите цвет бледнее, получая слева направо. Срез посередине полностью интерполируется и ранее не существовал.