Как я могу построить массив массивов x, y, z на трехмерном графике поверхности? - PullRequest
1 голос
/ 05 июня 2019

Я просмотрел оба из этих потоков , но все еще изо всех сил пытаюсь создать трехмерный график поверхности из массива numpy с x, y, z координатами.

Мой массив выглядит так:

>>> points
array([[ 322697.1875    , 3663966.5       ,  -30000.        ],
       [ 325054.34375   , 3663966.5       ,  -30000.        ],
       [ 325054.34375   , 3665679.5       ,  -30000.        ],
       [ 322697.1875    , 3665679.5       ,  -30000.        ],
       [ 322697.1875    , 3663966.5       ,  -27703.12304688],
       [ 325054.34375   , 3663966.5       ,  -27703.15429688],
       [ 325054.34375   , 3665679.5       ,  -27703.70703125],
       [ 322697.1875    , 3665679.5       ,  -27703.67382812]])

ax.plot_surface принимает x, y, z баллов, поэтому я преобразую приведенный выше массив в отдельные части ниже:

x = points[:, 0]
y = points[:, 1]
z = points[:, 2]

Затем я помещаю его в сетку для перехода в ax.plot_surface():

import numpy as np

X, Y, Z = np.meshgrid(x, y, z)

А потом попробуй построить:

import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
fig = plt.figure(figsize=(16,10))
ax = plt.axes(projection = '3d')
ax.plot_surface(X, Y, Z, alpha=0.5)
plt.show()

Когда я запускаю это, я получаю сообщение об ошибке: rows, cols = Z.shape ValueError: too many values to unpack (expected 2).

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

Я бы хотел, чтобы результат был похож на этот, но с моими данными: enter image description here

ОБНОВЛЕНИЕ: Если я не включу z в meshgrid, а только x и y, я получу этот вывод при запуске ax.plot_surface(X, Y, z, alpha=0.5): enter image description here

Это действительно близко, но я хочу, чтобы все стороны были заполнены. Только одна отображается как заполненная. Я добавил координаты точек, чтобы показать границы. Я чувствую, что это как-то связано с meshgrid, который я создаю. Вот вывод X, Y:

>>> X, Y = np.meshgrid(x, y)
(array([[322697.1875 , 325054.34375, 325054.34375, 322697.1875 ,
        322697.1875 , 325054.34375, 325054.34375, 322697.1875 ],
       [322697.1875 , 325054.34375, 325054.34375, 322697.1875 ,
        322697.1875 , 325054.34375, 325054.34375, 322697.1875 ],
       [322697.1875 , 325054.34375, 325054.34375, 322697.1875 ,
        322697.1875 , 325054.34375, 325054.34375, 322697.1875 ],
       [322697.1875 , 325054.34375, 325054.34375, 322697.1875 ,
        322697.1875 , 325054.34375, 325054.34375, 322697.1875 ],
       [322697.1875 , 325054.34375, 325054.34375, 322697.1875 ,
        322697.1875 , 325054.34375, 325054.34375, 322697.1875 ],
       [322697.1875 , 325054.34375, 325054.34375, 322697.1875 ,
        322697.1875 , 325054.34375, 325054.34375, 322697.1875 ],
       [322697.1875 , 325054.34375, 325054.34375, 322697.1875 ,
        322697.1875 , 325054.34375, 325054.34375, 322697.1875 ],
       [322697.1875 , 325054.34375, 325054.34375, 322697.1875 ,
        322697.1875 , 325054.34375, 325054.34375, 322697.1875 ]]), array([[3663966.5, 3663966.5, 3663966.5, 3663966.5, 3663966.5, 3663966.5,
        3663966.5, 3663966.5],
       [3663966.5, 3663966.5, 3663966.5, 3663966.5, 3663966.5, 3663966.5,
        3663966.5, 3663966.5],
       [3665679.5, 3665679.5, 3665679.5, 3665679.5, 3665679.5, 3665679.5,
        3665679.5, 3665679.5],
       [3665679.5, 3665679.5, 3665679.5, 3665679.5, 3665679.5, 3665679.5,
        3665679.5, 3665679.5],
       [3663966.5, 3663966.5, 3663966.5, 3663966.5, 3663966.5, 3663966.5,
        3663966.5, 3663966.5],
       [3663966.5, 3663966.5, 3663966.5, 3663966.5, 3663966.5, 3663966.5,
        3663966.5, 3663966.5],
       [3665679.5, 3665679.5, 3665679.5, 3665679.5, 3665679.5, 3665679.5,
        3665679.5, 3665679.5],
       [3665679.5, 3665679.5, 3665679.5, 3665679.5, 3665679.5, 3665679.5,
        3665679.5, 3665679.5]]))

Если я просто беру x, y уникальные значения, я получаю сообщение об ошибке:

x = np.unique(x)
y = np.unique(y)

>>> x
array([322697.1875 , 325054.34375])
>>> y
array([3663966.5, 3665679.5])

X, Y = np.meshgrid(x, y)
>>> X, Y
(array([[322697.1875 , 325054.34375],
       [322697.1875 , 325054.34375]]), array([[3663966.5, 3663966.5],
       [3665679.5, 3665679.5]]))

>>> ax.plot_surface(X, Y, z, alpha=0.5)
Traceback (most recent call last):
  File "<pyshell#61>", line 1, in <module>
    ax.plot_surface(X, Y, z, alpha=0.5)
  File "/Users/NaN/anaconda/envs/py36/lib/python3.6/site-packages/mpl_toolkits/mplot3d/axes3d.py", line 1586, in plot_surface
    X, Y, Z = np.broadcast_arrays(X, Y, Z)
  File "/Users/NaN/anaconda/envs/py36/lib/python3.6/site-packages/numpy/lib/stride_tricks.py", line 259, in broadcast_arrays
    shape = _broadcast_shape(*args)
  File "/Users/NaN/anaconda/envs/py36/lib/python3.6/site-packages/numpy/lib/stride_tricks.py", line 193, in _broadcast_shape
    b = np.broadcast(*args[:32])
ValueError: shape mismatch: objects cannot be broadcast to a single shape

1 Ответ

0 голосов
/ 06 июня 2019

Массивы x, y, z должны быть параметризованы в двух измерениях. Одним из способов сделать это является использование сферических координат, например, в Поверхности графика на кубе .

Остается задача отобрать уникальные координаты из входных данных. Я предполагаю, что в каждом измерении есть только 2 различных значения.

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

def get_cube():   
    phi = np.arange(1,10,2)*np.pi/4
    Phi, Theta = np.meshgrid(phi, phi)

    x = np.cos(Phi)*np.sin(Theta)
    y = np.sin(Phi)*np.sin(Theta)
    z = np.cos(Theta)/np.sqrt(2)
    return x,y,z


points = np.array([[ 322697.1875    , 3663966.5       ,  -30000. ],
                   [ 325054.34375   , 3663966.5       ,  -30000. ],
                   [ 325054.34375   , 3665679.5       ,  -30000. ],
                   [ 322697.1875    , 3665679.5       ,  -30000. ],
                   [ 322697.1875    , 3663966.5       ,  -27703.12],
                   [ 325054.34375   , 3663966.5       ,  -27703.12],
                   [ 325054.34375   , 3665679.5       ,  -27703.12],
                   [ 322697.1875    , 3665679.5       ,  -27703.12]])

ux = np.unique(points[:,0])
uy = np.unique(points[:,1])
uz = np.unique(points[:,2])

x,y,z = get_cube()
offset = lambda X, o: o[0] + (X+.5)*np.diff(o)[0]


fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')

ax.plot_surface(offset(x, ux), offset(y, uy), offset(z, uz))

plt.show()

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...