Sympy:生成具有多个子图的图形

2024-10-01 17:37:50 发布

您现在位置:Python中文网/ 问答频道 /正文

我使用的是sypy和matplotlib,希望生成一个具有多个绘图的图形,类似于使用pylab.子批次使用numpy时。这应该是微不足道的,或者我想。。。在

令我吃惊的是,我没有找到一个简单的方法来做这件事。或者(a)在多个点计算一个SymPy表达式并得到一个numpy数组,我可以用matplotlib来使用它;或者(b)使用类似于pylab.子批次在同谋. 在

样本代码:

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))

有什么想法吗?在


Tags: 方法importnumpy图形绘图matplotlib表达式as
3条回答

第二部分的答案可能是使用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)

此功能不是最新版本的一部分,但可能会在SymPy的下一个版本中提供。你可以在SymPy当前的development version中找到它。在

对于第一个问题,可以使用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中的绘图模块:

  1. 只需调用plot,就像在p = plot(expression, (var, start, stop))中一样。如果你有matplotlib,它将直接使用它。在
  2. 如果您想要一些奇特的东西,请提取matplotlib图:f = p._backend.fig。在
  3. 别再关心SymPy了,你剩下的工作都在matplotlib。你想做什么都行。在

SymPy绘图模块背后的想法是能够计算任何可能的表达式,而不是重新实现像matplotlib这样的绘图库。因此,只需使用sympy.plotting.plot进行求值,并在matplotlib中进行奇妙的子批转换。在

与老套的解决方案相比,使用sympy绘图模块还有其他优点:检测不连续性和自适应采样、根据函数着色、评估病理学上复杂的符号表达式(尽管速度较慢)。在

很明显,检查一下文件。虽然它们不是很好,但有许多问题得到了回答:http://docs.sympy.org/0.7.2/modules/plotting.html还可以查看sympy示例文件夹中的笔记本。在

编辑以解决一些附加问题:

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

  2. 为了在matplotlib中从两个不同的sympy plot创建一个图形(这是一个难看的方法,因为matplotlib不支持图形的合并):

    sympy_p1 = sympy.plot(foo)
    sympy_p2 = sympy.plot(bar)
    matplotlib_fig = plt.figure()
    sp1 = matplotlib_fig.add_subplot(121)
    sp2 = matplotlib_fig.add_subplot(122)
    sp1.add_collection(sympy_p1._backend.ax.get_children()[appropriate_index])
    sp2.add_collection(sympy_p2._backend.ax.get_children()[appropriate_index])
    matplotlib_fig.show()
    
  3. 为了更新sympy plot(不是创建子批,只是添加一个新的表达式),请使用sympy_p1.append(sympy_p2)。这将导致sympy_p1同时包含foo和{}(不是两个子图,而是包含两个表达式的一个plot)。

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

相关问题 更多 >

    热门问题