як встановити "положення камери" для 3d-сюжетів за допомогою python / matplotlib?


134

Я вивчаю, як використовувати mplot3d для отримання приємних сюжетів 3d даних, і поки що дуже задоволений. На даний момент я намагаюся зробити трохи анімації обертової поверхні. Для цього мені потрібно встановити положення камери для 3D-проекції. Я думаю, що це повинно бути можливим, оскільки поверхня може обертатися за допомогою миші при інтерактивному використанні matplotlib. Але як це зробити зі сценарію? Я знайшов багато перетворень у mpl_toolkits.mplot3d.proj3d, але я не міг з'ясувати, як їх використовувати для своїх цілей, і я не знайшов приклад того, що намагаюся зробити.


2
Бічна примітка для тих, хто цікавиться, як інтерактивно обертатись у зошиті з юпітера: ви можете використовувати%matplotlib notebook
YvesgereY

Також перетягування, утримуючи праву кнопку миші, змінює відстань до камери.
LoMaPh

Для подібної візуалізації я б спробував майаві.
Тактопода

Відповіді:


158

За "положенням камери" це звучить так, як ви хочете відрегулювати висоту та кут азимуту, який ви використовуєте для перегляду 3D-графіку. Ви можете встановити це за допомогою ax.view_init. Я використовував наведений нижче сценарій, щоб спершу створити сюжет, потім визначив хорошу висоту, або elevз якої переглянути свій сюжет. Потім я відкоригував кут азимуту, або azim, щоб змінити повний 360 градусів навколо мого ділянки, зберігаючи фігуру в кожному екземплярі (і відзначаючи, який кут азимута, коли я зберігав графік). Для більш складного спуску камери ви можете регулювати як висоту, так і кут, щоб досягти бажаного ефекту.

    from mpl_toolkits.mplot3d import Axes3D
    ax = Axes3D(fig)
    ax.scatter(xx,yy,zz, marker='o', s=20, c="goldenrod", alpha=0.6)
    for ii in xrange(0,360,1):
        ax.view_init(elev=10., azim=ii)
        savefig("movie%d.png" % ii)

26
Бий мене до цього! З іншого боку, вони доступні як ax.elevі ax.azimвластивості. Ви також могли просто писати ax.azim = iiабо навіть ax.azim += 1домогтися того ж ефекту.
Джо Кінгтон

1
Вибачте, що я побив вас, але справедливі бали навколо. Це також просто мій уривок кодування, в цьому for-loop було більше, ніж просто view_init та savefig. =)
космос

4
Дякую космосу та Джо, саме це я шукав. Оскільки я тепер знав, на що звернути увагу, я також знайшов ax.dist, який разом із ax.azim та ax.elev - дозволяє встановлювати положення камери у полярних координатах.
Андреас Блелер

Якщо це відповідь - ви можете, будь ласка, поставити галочку? Дякую.
космос

12
Ви також можете встановити відстань між камерою та точкою об’єкта по ax.dist = 15 (за замовчуванням - 10)
Тим

14

Було б зручно застосувати положення камери до нового сюжету. Тож я малюю, а потім переміщую сюжет навколо миші, змінюючи відстань. Потім спробуйте повторити вигляд, включаючи відстань на іншій ділянці. Я вважаю, що axx.ax.get_axes () отримує мені об'єкт зі старими .azim та .elev.

В ПІТОНІ ...

axx=ax1.get_axes()
azm=axx.azim
ele=axx.elev
dst=axx.dist       # ALWAYS GIVES 10
#dst=ax1.axes.dist # ALWAYS GIVES 10
#dst=ax1.dist      # ALWAYS GIVES 10

Пізніше 3d графік ...

ax2.view_init(elev=ele, azim=azm) #Works!
ax2.dist=dst                       # works but always 10 from axx

EDIT 1 ... Гаразд, положення камери - це неправильний спосіб мислення щодо значення .dist. Він перебуває на вершині всього, як своєрідний хокейний скалярний множник для всього графіка.

Це працює для збільшення / збільшення зображення:

xlm=ax1.get_xlim3d() #These are two tupples
ylm=ax1.get_ylim3d() #we use them in the next
zlm=ax1.get_zlim3d() #graph to reproduce the magnification from mousing
axx=ax1.get_axes()
azm=axx.azim
ele=axx.elev

Пізніше графік ...

ax2.view_init(elev=ele, azim=azm) #Reproduce view
ax2.set_xlim3d(xlm[0],xlm[1])     #Reproduce magnification
ax2.set_ylim3d(ylm[0],ylm[1])     #...
ax2.set_zlim3d(zlm[0],zlm[1])     #...

+1 для виклику шаленого скалярного множення. Це дуже дратує, якщо ви сподівалися на перспективу.
користувач5920660
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.