(matplotlib) 和 (SymPy 绘图模块) 有什么区别?

What is the difference between (matplotlib) and (SymPy Plotting Module)?

https://scicomp.stackexchange.com/questions/1144/how-can-i-plot-piece-wise-defined-function-in-some-easily-accessed-open-source-t

①为什么上面的源码可以制作剧情,下面的源码却不行?

②你能给我指一个有table比较(matplotlib)和(SymPy绘图模块)的网站吗?

③(matplotlib) 到 (SymPy 绘图模块) 转换器和一个 (SymPy 绘图模块) 到 (matplotlib) 转换器会很有帮助。

from sympy import *

def define_fn(n):
    def fn(x):
        if n <= x <= n + 1:
            return float(x) - n
        elif n + 1 <= x <= n + 2:
            return 2.0 - x + n
        else:
            return 0.0
    return fn
f3 = define_fn(3)
f8 = define_fn(8)

print("#",f3)
print("#",f8)
plot(f3,f8)
# <function define_fn.<locals>.fn at 0x000002474E838280>
# <function define_fn.<locals>.fn at 0x000002474E838310>
# SymPyDeprecationWarning: .............

①Why is it that the above source code can be used to create a plot, but the following source code cannot?

链接示例使用 matplotlib,它可以处理数字输入。 Matplotlib 不知道 sympy 的世界。

Sympy 的绘图模块将 sympy 表达式转换为数值近似值并使用 matplotlib 绘制它们。 Sympy 的 plot 模块抽象出许多复杂的东西来完成这项工作,并对临时用户隐藏这些内容。

②Can you point me to a web site that has a table comparing (matplotlib) and (SymPy Plotting Module)?

Matplotlib 非常庞大。 Sympy 的绘图模块使用了一个功能子集,仔细而巧妙地适应了符号世界。差异不适合 table。可以找到 Matplotlib 的大量文档 at matplotlib.org, but most people only look into the subset they are using. Sympy's plotting documentation fits onto one large webpage。对于这两个库,您将需要额外的教程、StackOverlow,如果您需要不容易获得的功能,还可能需要深入研究免费提供的源代码。

③(matplotlib) to (SymPy Plotting Module) converter and a (SymPy Plotting Module) to (matplotlib) converter would be helpful.

这将是一项艰巨的工作,有很多未定义的案例。 Sympy(以及 matplotlib)由非常有才华的志愿者开发,资源有限。

请注意,如果你真的想要,你可以 并在那里扩展情节。

这是您的源代码在 sympy 中的样子。 先说几点:

  • sympy 函数和表达式不能与 Python 的 if 测试一起使用,您需要符号函数,例如 PieceWise
  • float(x) 不适用于 sympy 的符号
  • 一般来说,sympy 试图避免浮点数,因为它们根据定义是近似的,而 sympy 几乎总是寻找精确的符号解
from sympy import plot, Symbol, Piecewise, And

def define_fn(n):
    def fn(x):
        return Piecewise((x - n, (n <= x) & (x <= n + 1)),
                         (2 - x + n, (n + 1 <= x) & (x <= n + 2)),
                         (0, True))
    return fn

f3 = define_fn(3)
f8 = define_fn(8)

x = Symbol('x', real=True)
plot(f3(x), f8(x), (x, -1, 11))

虽然这可行,但这不是 sympy 的标准方式。通常,函数被写成表达式。请注意 f3 如何用作包含 x 的表达式,而不是前面示例中不太灵活的 f3(x)

from sympy import plot, Symbol, Piecewise, And

x = Symbol('x', real=True)
n = Symbol('n', real=True)

fn = Piecewise((x - n, (n <= x) & (x <= n + 1)),
               (2 - x + n, (n + 1 <= x) & (x <= n + 2)),
               (0, True))

f3 = fn.subs(n, 3)  # Piecewise((x - 3, (x >= 3) & (x <= 4)), (5 - x, (x >= 4) & (x <= 5)), (0, True))
f8 = fn.subs(n, 8)  # Piecewise((x - 8, (x >= 8) & (x <= 9)), (10 - x, (x >= 9) & (x <= 10)), (0, True))

plot(f3, f8, (x, -1, 11))

让我们确保您了解 link 和您的改编正在做什么。您关于绘图包差异的问题表明您不清楚哪个包在做什么。

您定义了两个 python 函数,它们接受一个数字。

In [11]: f3(4)
Out[11]: 1.0
In [12]: f8(9)
Out[12]: 1.0

只需 python 我们就可以创建一个包含 x 个值的列表:

In [17]: x = [i / 10 for i in range(120)]

对应的y值:

In [18]: y1 = [f3(i) for i in x]
In [19]: y2 = [f8(i) for i in x]

并绘制它们:

In [20]: plt.plot(x, y1, x, y2)
Out[20]: 
[<matplotlib.lines.Line2D at 0x7fe2589385e0>,
 <matplotlib.lines.Line2D at 0x7fe258938610>]
# plotted as you show

link 使用 np.linspacex 值创建为数组,并使用 np.vectorize 将函数应用于所有这些值。 matplotlib 适用于数组和列表。

matplotlib.

的这种用法没什么特别的

语句如下:

    if n <= x <= n + 1:
        return float(x) - n

仅适用于单个数字。这是基本的 python。为 x 或 sympy symbolexpression 使用 numpy 数组将导致错误。

如果x是一个sympy符号:

In [3]: f3(x)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Input In [3], in <module>
----> 1 f3(x)

Input In [1], in define_fn.<locals>.fn(x)
      2 def fn(x):
----> 3     if n <= x <= n + 1:
      4         return float(x) - n
      5     elif n + 1 <= x <= n + 2:

File /usr/local/lib/python3.8/dist-packages/sympy/core/relational.py:398, in Relational.__bool__(self)
    397 def __bool__(self):
--> 398     raise TypeError("cannot determine truth value of Relational")

TypeError: cannot determine truth value of Relational

和一个数组:

In [4]: f3(np.arange(3))
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Input In [4], in <module>
----> 1 f3(np.arange(3))

Input In [1], in define_fn.<locals>.fn(x)
      2 def fn(x):
----> 3     if n <= x <= n + 1:
      4         return float(x) - n
      5     elif n + 1 <= x <= n + 2:

ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
print("#",type(f3),f3)
print("#",type(f8),f8)
# <class 'function'> <function define_fn.<locals>.fn at 0x00000246464B9280>
# <class 'function'> <function define_fn.<locals>.fn at 0x00000246464B9310>

print("#",type(f3(x)),f3(x))
print("#",type(f8(x)),f8(x))
# Piecewise Piecewise((x - 3, (x >= 3) & (x <= 4)), (5 - x, (x >= 4) & (x <= 5)), (0, True))
# Piecewise Piecewise((x - 8, (x >= 8) & (x <= 9)), (10 - x, (x >= 9) & (x <= 10)), (0, True))

print("#",type(f3),f3)
print("#",type(f8),f8)
# Piecewise Piecewise((x - 3, (x >= 3) & (x <= 4)), (5 - x, (x >= 4) & (x <= 5)), (0, True))
# Piecewise Piecewise((x - 8, (x >= 8) & (x <= 9)), (10 - x, (x >= 9) & (x <= 10)), (0, True))