Как построить 3D коллекцию патчей в matplotlib? - PullRequest
9 голосов
/ 10 июня 2011

Я пытаюсь создать трехмерный график в matplotlib с тремя кружками на нем, каждый из которых центрирован в начале координат и радиусом 1, указывающим в разных направлениях - например, для иллюстрации сферы радиусом 1.

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

import matplotlib
import matplotlib.pyplot as P
import mpl_toolkits.mplot3d as M3

fig = P.figure()
ax = fig.add_subplot(1, 1, 1, projection='3d')
circles = matplotlib.collections.PatchCollection(
    [matplotlib.patches.Circle((0, 0), 1) for count in range(3)],
    offsets=(0, 0))
M3.art3d.patch_collection_2d_to_3d(circles, zs=[0], zdir='z')
ax.add_collection(circles)
P.show()

Запуск этой программы заполняет все окно графика синим цветом, т.е. цветом лица участков, независимо от того, как я поворачиваю график. Если я установлю facecolor='none' в вызове PatchCollection(), то появится пустой Axes3D.

Вещи, которые я пробовал:

  • Если я использую CircleCollection вместо PatchCollection, патчи вообще не отображаются.
  • Параметр zs в вызове patch_collection_2d_to_3d() нечетен; Я ожидал бы поставить либо zs=0 (одна z-координата для всех трех патчей), либо zs=[0,0,0] (отдельная z-координата для каждого патча), но оба из них выдают ошибку:

    ValueError: установка элемента массива с последовательностью.

  • Чтобы по-разному ориентировать патчи, я ожидал, что смогу пропустить что-то вроде zdir=['x', 'y', 'z'], но результаты не отличаются, независимо от того, пропущу я это или 'z' или ['z'].

  • Я бы также ожидал, что смогу сделать ax.add_collection3d(circles, zs=[0, 0, 0], zdir=['x', 'y', 'z']) вместо преобразования коллекции патчей из 2d в 3d, но это также выдает ошибку:

    AttributeError: у объекта 'Patch3DCollection' нет атрибута 'set_sort_zpos'

1 Ответ

12 голосов
/ 15 июня 2011
import matplotlib.pyplot as plt
from matplotlib.patches import Circle, PathPatch
from mpl_toolkits.mplot3d import Axes3D 
import mpl_toolkits.mplot3d.art3d as art3d


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

for i in ["x","y","z"]:
    circle = Circle((0, 0), 1)
    ax.add_patch(circle)
    art3d.pathpatch_2d_to_3d(circle, z=0, zdir=i)


ax.set_xlim3d(-2, 2)
ax.set_ylim3d(-2, 2)
ax.set_zlim3d(-2, 2)

plt.show()
...