Python 3D построение данных измерений

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

У меня большие трудности с представлением данных. Я пробовал несколько вариантов. Это последнее, что я сейчас пытаюсь:

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

nElevationPoints = 16
nAzimuthPoints = 40
stepSizeRad = 0.05 * np.pi
def r(phi,theta):
    radius = 1
    return radius

phi = np.arange(0,nAzimuthPoints*stepSizeRad,stepSizeRad)
theta = np.arange(0,nElevationPoints*stepSizeRad,stepSizeRad)

x = (r(phi,theta)*np.outer(r(phi,theta)*np.cos(phi), np.sin(theta)))
y = (-r(phi,theta)*np.outer(np.sin(phi), np.sin(theta)))
z = (r(phi,theta)*np.outer(np.ones(np.size(phi)), np.cos(theta)))

fig = plt.figure(1)
ax = fig.add_subplot(111, projection='3d')
ax.plot_surface(x, y, z,  rstride=4, cstride=4, color='b')

plt.ioff()
plt.show()

Этот код сам по себе работает, и он строит сферу. Теперь дело в том, что в соответствии с данными измерений мне действительно нужно, чтобы радиус был не постоянным "1", а соответствовал измеренной интенсивности излучения. Так что это должно быть функцией фи, тета.

Однако, как только я изменяю функцию "r" на что-либо, содержащее параметр phi или theta, я получаю ошибку об операндах, которые не могут быть переданы.

Если есть какая-то работа, которая проходит через фи, то и тета тоже будет в порядке.

Но я застрял сейчас, поэтому я был бы признателен за любую помощь:-)

Кстати, причина, по которой я пошел по вышеупомянутому подходу, состоит в том, что я не мог понять, как x,y,z должны быть определены, чтобы быть приемлемыми для функции plot_surface. Мне удалось сгенерировать график рассеяния, рассчитав фактические положения (x,y,z) из данных фи, тета, интенсивности, но это только представление отдельными точками и не генерирует хорошо видимую диаграмму направленности антенны. сюжет. Для этого я предполагаю, что контурный график был бы лучше, но опять же я застрял при вызове функции "r" или при понимании того, как x,y,z следует отформатировать (документация ссылается на x,y,z, требующие быть двумерными массивами, но это вне моего понимания, так как x,y,z обычно сами по себе являются одномерными массивами).

В любом случае, с нетерпением жду любой помощи, которую кто-то может пожелать оказать.

-- РЕДАКТИРОВАТЬ --

С предложенными @M4rtini изменениями я пришел к следующему:

import numpy as np
from mayavi import mlab

def r(phi,theta):
    r = np.sin(phi)**2
    return r


phi, theta = np.mgrid[0:2*np.pi:201j, 0:np.pi:101j]

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

intensity = phi * theta

obj = mlab.mesh(x, y, z, scalars=intensity, colormap='jet')
obj.enable_contours = True
obj.contour.filled_contours = True
obj.contour.number_of_contours = 20
mlab.show()

Это работает, спасибо, @M4rtini, и теперь у меня есть фи-зависимая функция "r". Тем не менее, отметил, что пример теперь гарантирует, что фи и тета имеют одинаковую длину (из-за функции mgrid). Это не так в моем измерении. Если объявлять фи и тэту отдельно и в разных измерениях, это не работает до сих пор. Итак, я сейчас посмотрю на интерполяцию измерений.

1 ответ

Решение

Это может быть не точный ответ, который вы искали, но если вы можете согласиться с использованием значений интенсивности в качестве отображения цвета, это должно сработать.
На самом деле, вы также можете рассчитать конкретное значение r здесь. Но я не проверял это.
Использование Mayavi, поскольку он, на мой взгляд, намного лучше, чем Matplotlib для 3D.

import numpy as np
from mayavi import mlab
r = 1.0
phi, theta = np.mgrid[0:np.pi:200j, 0:2*np.pi:101j]

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

intensity = phi * theta

obj = mlab.mesh(x, y, z, scalars=intensity, colormap='jet')
obj.enable_contours = True
obj.contour.filled_contours = True
obj.contour.number_of_contours = 20
mlab.show()

Вывод примера скрипта, теперь это в интерактивном интерфейсе. так что вы можете вращать, переводить, масштабировать, как вам угодно. И даже в интерактивном режиме манипулируют данными и параметрами представления.Вывод примера скрипта

Другие вопросы по тегам