如何用matplotlib画一般方程?
How to draw a general equation with matplotlib?
已研究以下问题 - 主要是 python 中的 matplotlib。
“基本”函数是可能的,例如 y = x^2
,但是如果我想绘制一个方程(由于有多个 x-y 关联,它不一定是函数),例如:
x^2 + y^2 = 1
(二维坐标系中以点(0/0)为中心,半径为1的基本圆)
有没有办法用 matplotlib 或任何类似的库绘制这样的方程?
我想到了将方程重写为可绘制函数的想法,但由于绝对值赋值,它看起来比原始方程更难,例如上面的等式变成一个“函数”:|y| = sqrt(1-x²)
with -y
and +y
.
//编辑:应@mkrieger1 的要求编辑此问题。
我的软件的目的是使用输入(由另一个函数给出;代表任何方程式的字符串,例如 "y^3-sqrt(sin(x^2)-2)*2 = 3x"
)并将其转换为绘图。我个人未能使用解决 y 函数的方法(如前所述),尤其是对于更复杂的函数。考虑到数学输入的多样性,将这些方程拆分为“更小的部分”也非常困难,因此我认为采用轮廓求解方法将是最好的部分。 (正如@mkrieger1 建议的那样)。
再一次,这种方法是至关重要的,因为在 plt.contour(X, Y, func, [0])
中实现它之前需要对等式进行“编辑”,以及稍后的 UserWarning。
你也可以使用sympy to convert an expression in a string to an equation and then plot它。我省略了示例的 -2
,因为这会导致一个非常空的情节。 Sympy 的解析器支持特殊函数以允许省略乘法(如 3x
)并将 Python 的异或函数(^
)转换为幂。
from sympy import plot_implicit, Eq
from sympy.parsing.sympy_parser import parse_expr
from sympy.parsing.sympy_parser import standard_transformations, convert_xor, implicit_multiplication
string = "y^3-sqrt(sin(x^2))*2 = 3x"
transformations = (standard_transformations + (implicit_multiplication,) + (convert_xor,))
lhs = parse_expr(string.split('=')[0], transformations=transformations)
rhs = parse_expr(string.split('=')[1], transformations=transformations)
plot_implicit(Eq(lhs, rhs))
另一个例子:
from sympy import plot_implicit, Eq, cos
from sympy.abc import x, y
plot_implicit(Eq(x/y, cos(y)), (x, -10, 10), (y, -10, 10))
请注意,如果没有明确设置变量的范围,plot_implicit
假设默认范围介于 -5 和 5 之间。
如果您完全使用 matplotlib,您会注意到 plot
接受一对等长的数组,表示 x-y 对的序列。它不了解函数、方程式或您提到的任何其他概念。
因此,支持绘制简单函数的断言在很大程度上是没有意义的,即使是真的。话虽如此,转换笛卡尔 space 中非函数的东西(如圆)的标准方法是对其进行参数化。许多流行的非函数的一种可能的参数化是使用极坐标。
例如:
t = np.linspace(0, 2 * np.pi, 100) # the parameter
x = np.cos(t)
y = np.sin(t)
已研究以下问题 - 主要是 python 中的 matplotlib。
“基本”函数是可能的,例如 y = x^2
,但是如果我想绘制一个方程(由于有多个 x-y 关联,它不一定是函数),例如:
x^2 + y^2 = 1
(二维坐标系中以点(0/0)为中心,半径为1的基本圆)
有没有办法用 matplotlib 或任何类似的库绘制这样的方程?
我想到了将方程重写为可绘制函数的想法,但由于绝对值赋值,它看起来比原始方程更难,例如上面的等式变成一个“函数”:|y| = sqrt(1-x²)
with -y
and +y
.
//编辑:应@mkrieger1 的要求编辑此问题。
我的软件的目的是使用输入(由另一个函数给出;代表任何方程式的字符串,例如 "y^3-sqrt(sin(x^2)-2)*2 = 3x"
)并将其转换为绘图。我个人未能使用解决 y 函数的方法(如前所述),尤其是对于更复杂的函数。考虑到数学输入的多样性,将这些方程拆分为“更小的部分”也非常困难,因此我认为采用轮廓求解方法将是最好的部分。 (正如@mkrieger1 建议的那样)。
再一次,这种方法是至关重要的,因为在 plt.contour(X, Y, func, [0])
中实现它之前需要对等式进行“编辑”,以及稍后的 UserWarning。
你也可以使用sympy to convert an expression in a string to an equation and then plot它。我省略了示例的 -2
,因为这会导致一个非常空的情节。 Sympy 的解析器支持特殊函数以允许省略乘法(如 3x
)并将 Python 的异或函数(^
)转换为幂。
from sympy import plot_implicit, Eq
from sympy.parsing.sympy_parser import parse_expr
from sympy.parsing.sympy_parser import standard_transformations, convert_xor, implicit_multiplication
string = "y^3-sqrt(sin(x^2))*2 = 3x"
transformations = (standard_transformations + (implicit_multiplication,) + (convert_xor,))
lhs = parse_expr(string.split('=')[0], transformations=transformations)
rhs = parse_expr(string.split('=')[1], transformations=transformations)
plot_implicit(Eq(lhs, rhs))
另一个例子:
from sympy import plot_implicit, Eq, cos
from sympy.abc import x, y
plot_implicit(Eq(x/y, cos(y)), (x, -10, 10), (y, -10, 10))
请注意,如果没有明确设置变量的范围,plot_implicit
假设默认范围介于 -5 和 5 之间。
如果您完全使用 matplotlib,您会注意到 plot
接受一对等长的数组,表示 x-y 对的序列。它不了解函数、方程式或您提到的任何其他概念。
因此,支持绘制简单函数的断言在很大程度上是没有意义的,即使是真的。话虽如此,转换笛卡尔 space 中非函数的东西(如圆)的标准方法是对其进行参数化。许多流行的非函数的一种可能的参数化是使用极坐标。
例如:
t = np.linspace(0, 2 * np.pi, 100) # the parameter
x = np.cos(t)
y = np.sin(t)