Использование sympy с Mayavi

У меня есть проект, в котором я хотел бы отобразить результаты некоторых манипуляций SymPy с mayavi. В частности, я хотел бы использовать какую-нибудь функцию в contour3d. Вот что я придумал, но это не работает

#!/usr/bin/env python2

from sympy import *
from mayavi.mlab import *
from functools import partial
import numpy as np

def XYZ(f, xp, yp, zp):
  return f.evalf(subs={x:xp,y:yp,z:zp})


x, y, z = symbols('x y z')
r=x**2+y**2+z**2

F=partial(XYZ, r)

X, Y, Z = np.mgrid[-3:3:50j, -3:3:50j, -3:3:50j]

obj=contour3d(X, Y, Z, F)

Однако появляются две ошибки (обе от sympify)

1.) Как написано, ошибка

ValueError: sequence too large; must be smaller than 32

2.) Уменьшение количества точек (до 10 в каждую сторону)

ValueError: negative dimensions are not allowed

Есть мысли о том, как заставить что-то подобное работать? Я думаю, эти два пакета будут хорошо работать вместе.


person Benjamin Pritchard    schedule 12.12.2013    source источник


Ответы (1)


Прежде всего, я хотел бы отметить, что команда SymPy была бы очень благодарна, если вы добавите бэкэнд mayavi для нашего модуля построения графиков (на данный момент у нас есть только бэкэнд matplotlib, который не очень хорош для 3D).

Суть вашей проблемы, похоже, в том, что numpy и sympy плохо взаимодействуют. В принципе, вы не должны ожидать (по крайней мере, на данный момент), что функции sympy знают, как оценивать входные данные массива (они не являются u-функциями, как было бы сказано в numpy).

Текущее решение этой проблемы - использовать lambdify. У него есть свои проблемы, но он работает достаточно хорошо. Аналогичная, но закрытая функция, называемая experimental_lambdify, используется для собственного модуля рисования sympy. Посмотреть здесь:

https://github.com/sympy/sympy/blob/master/sympy/plotting/plot.py#L750

В частности get_meshes(). Или все остальные get_something методы. Если вы ленивы, вы можете просто повторно использовать их, создав объект sympy Plot, не отображая его в matplotlib:

your_plot_object = plot3d_parametric_surface(expr_x, expr_y, expr_z, range_u, range_v, show=False)
the_single_geometrical_object_in_this_plot = your_plot_object[0]
your_meshes = the_single_geometrical_object_in_this_plot.get_meshes()
person Krastanov    schedule 13.12.2013
comment
Что ж, я привожу пример параметрической поверхности, поэтому он не будет работать непосредственно в вашем случае, но вы можете просто скопировать и вставить соответствующий код из get_meshes (), а остальное импортировать из текущего модуля рисования sympy. Опять же, команда была бы признательна за вклад в создание нового бэкэнда для построения графиков. - person Krastanov; 13.12.2013
comment
К сожалению, сейчас я вряд ли буду достаточно опытным, чтобы на самом деле реализовать подобный бэкэнд. Однако это была бы очень крутая функция. - person Benjamin Pritchard; 13.12.2013
comment
Да, было бы здорово заставить mayavi работать с SymPy, особенно теперь, когда Anaconda поставляется с mayavi, поэтому я могу установить его на свой Mac. - person asmeurer; 17.12.2013