Python Sympy:生成具有多个子地块的地物

Python Sympy:生成具有多个子地块的地物,python,numpy,matplotlib,sympy,Python,Numpy,Matplotlib,Sympy,我正在使用sympy和matplotlib,并希望生成一个具有多个绘图的图形,类似于使用numpy时使用pylab.subplot的方式。这应该是微不足道的,或者我认为 令我惊讶的是,我没有找到一个简单的方法。(a)在多个点上计算Symphy表达式并获得一个numpy数组,我可以使用matplotlib,或者(b)使用类似Symphy.plotting中pylab.subplot的机制 示例代码: import sympy.plotting.plot as symplot import symp

我正在使用sympy和matplotlib,并希望生成一个具有多个绘图的图形,类似于使用numpy时使用pylab.subplot的方式。这应该是微不足道的,或者我认为

令我惊讶的是,我没有找到一个简单的方法。(a)在多个点上计算Symphy表达式并获得一个numpy数组,我可以使用matplotlib,或者(b)使用类似Symphy.plotting中pylab.subplot的机制

示例代码:

import sympy.plotting.plot as symplot
import sympy as sym
x = sym.Symbol('x')
# This opens two different figures...
symplot(x*x, (x, -10, 10))
symplot(x, (x, -10, 10))

有什么想法吗?

对于第一个问题,您可以使用
lambdify()
将表达式转换为函数:

import numpy as np
from sympy import *

x, y = symbols("x, y")
eq = sqrt(x**2 + y**2)

xa = np.random.rand(10)
ya = np.random.rand(10)
f = lambdify((x, y),eq,'numpy')

print f(xa, ya)
print np.sqrt(xa**2 + ya**2)

这取决于您使用的SymPy版本

在最新版本(0.7.2)中,您已经有了一个打印模块,该模块保证能够打印任何内容,并且可以用作后端matplotlib

在较旧的版本中,您可以选择使用
lambdify
,这是一个粗糙的、大多已损坏的辅助函数,返回一个与numpy一起使用的快速数值函数。但是,对于非平凡表达式,它会中断

下面我将解释如何使用0.7.2中的绘图模块:

  • 只需调用
    plot
    就像
    p=plot(表达式,(var,start,stop))
    一样。如果您有
    matplotlib
    ,它将直接使用它
  • 如果您想要一些新奇的东西,请提取
    matplotlib
    图:
    f=p.\u backend.fig
  • 不要再关心SymPy了,剩下的工作都在
    matplotlib
    中。你想做什么就做什么
  • Symphy绘图模块背后的思想是能够计算任何可能的表达式,而不是重新实现matplotlib之类的绘图库。因此,只需使用
    sympy.plotting.plot
    进行计算,并在matplotlib中进行奇特的子地块转换

    使用Symphy plotting模块与黑客解决方案相比还有其他优势:检测不连续性和自适应采样、根据函数着色、评估病理复杂的符号表达式(尽管速度较慢)

    显然,检查一下文件。虽然它们不是很好,但很多问题都有答案:也可以查看sympy示例文件夹中的笔记本

    编辑以解决一些其他问题:

  • SymPy的绘图模块中没有子绘图的概念,希望永远不会有子绘图。正如我前面提到的,Symphy并没有试图重新实现像
    matplotlib
    这样的模块,而是试图提供在另一个模块中易于使用所必需的工具(模块之间的接口比包含许多小子模块的大项目更好)

  • 为了在matplotlib中从两个不同的Symphy绘图创建一个具有两个子绘图的地物,请执行以下操作(这是一个难看的操作,因为matplotlib不支持地物合并):

  • 要更新Symphy绘图(不是创建子绘图,只是添加新表达式),请使用
    Symphy\u p1.append(Symphy\u p2)
    。这将导致
    sympy_p1
    包含
    foo
    bar
    的绘图(不是两个子绘图,而是一个包含两个表达式的绘图)

  • 在某些情况下,您可能需要使用
    sympy.plot(…,show=False)


  • 第二部分的答案可能是使用PlotGrid类:

    >>> p1 = plot(x*x, (x, -10, 10), show=False)
    >>> p2 = plot(x, (x, -10, 10), show=False)   
    >>> PlotGrid(2, 1 , p1, p2)     # grid size or subplot size: 2x1
    PlotGrid object containing:
    Plot[0]:Plot object containing:
    [0]: cartesian line: x*x for x over (x, -10, 10)
    Plot[1]:Plot object containing:
    [0]: cartesian line: x for x over (x, -10, 10)
    

    此功能不是最新版本的一部分,但可能会在下一版本的Symphy中提供。你可以在《当代交响乐》中找到它。

    我认为这个问题有点太抽象了。用一些具体的例子进行编辑可能会有所帮助……您希望在同一个绘图上叠加子绘图还是两条线?我已经回答了第一个问题。对于第二个,只需对表达式进行分组。正如您所理解的,我需要matplotlib样式。
    lambdify
    在任何非平凡的输入上都会失败。对于新奇的东西,您可以使用
    expression.evalf(subs=arg)
    在值数组上循环,但这是用python完成的,并且精度高于机器精度,因此速度很慢;只是在某些绘图处计算的函数。。。总比没有好,我会试试。我错过的一件事,也是文档没有说的,就是如何让sympy重用一个图形,而不是打开一个新图形。在您的建议中,如何在matplotlib的两个不同子批次中使用Symphy生成两个绘图?谢谢@乌里科恩,我想我已经在上面的编辑中回答了你的问题。我没有测试代码,但它应该可以工作-如果有问题,请警告我,我会解决它。我认为最新版本的Symphy在Plot对象中没有_backend,只有backend,它是一个没有ax成员的DefaultBackend实例。
    \u backend
    属性是在
    show
    save
    上创建的。它就在那里,它不同于
    后端
    。我已经修复了代码。似乎
    matplotlib
    不允许合并图形。我怀疑子图是否会在
    sympy
    方面实现,因为它只会复制许多matplotlib功能。在完美世界中,图形合并功能将添加到matplotlib。
    >>> p1 = plot(x*x, (x, -10, 10), show=False)
    >>> p2 = plot(x, (x, -10, 10), show=False)   
    >>> PlotGrid(2, 1 , p1, p2)     # grid size or subplot size: 2x1
    PlotGrid object containing:
    Plot[0]:Plot object containing:
    [0]: cartesian line: x*x for x over (x, -10, 10)
    Plot[1]:Plot object containing:
    [0]: cartesian line: x for x over (x, -10, 10)