我仍在学习Python / Matplotlib,请耐心等待。
我有一个复杂的函数foo(x,y)
,带有两个输入参数x
和y
。我希望绘制此函数foo
的零轮廓图。我使用numpy.meshgrid
在所需范围内创建了一个网格,并尝试使用命令plt.contour(X,Y,Z,levels=[0])
绘制零轮廓。这给了我警告:No contour levels were found within the data range
。我认为这是因为函数是在一组离散值上求值的,其中精确地 从不为零,因此没有轮廓。
因此,我希望为此公差指定一个公差。有人可以建议我一种方法吗?非常感谢你!
答案 0 :(得分:0)
这当然取决于您的功能,但是不是,因为没有网格Point的值精确为零(实际上,这会使该图变得毫无用处...)
函数的重要属性及其查看空间是afaik:您的函数是否真的交叉在您感兴趣的区域中是您请求的级别,还是仅被触摸过的级别<? / em>两个数据点之间?
考虑功能
f(x,y) = (x - .5)**2 * (y - .5)**2
在x = .5和y = .5处将为零。 -但您会收到与上述报告相同的警告。 x = y = [-1,0,1]是确定的,但是即使x和y向量中包含0.5,警告仍然存在-即使大多数解在图中被标记为正确。
看看十字路口的文物;这是由于警告。
一旦您真正跨过所请求的级别,这里为零,一切正常,只需尝试:
f(x,y) = (x - .5)**2 * (y - .5)**2 -1
此功能没有警告,该功能实际上在查看区域内为零,因此这是可靠的结果。
答案 1 :(得分:0)
也许您有另一种方法,您是否已经听说过sympy
?可以在Python中进行符号数学运算(例如使用Mathematica或Maple)。
导入后
from sympy import *
您可以定义符号并将其应用于python变量
x, y = symbols('x y')
然后您可以定义描述这些符号功能的表达式
f = (x - .5)**2 * (y - .5)**2
寻找过零/接触零将是非线性求解器任务
result = nonlinsolve([f], [x, y])
result
{(0.499999999999937, y), (0.500000000000057, y), (x, 0.499999999999937), (x, 0.500000000000057)}
它显然仍然有计算上的错误-但是至少没有像plt.contour(...)这样的大工件区域。
但是,您正在寻找一种解决方案,该解决方案会返回某种公差,并且结果可以这样解释。
甚至还有一个函数,称为lambdify
。借助该函数,您可以通过numpy表达式将这些结果再次转换为可绘制数据的数组。
但是,此应谨慎使用,因为它在内部使用eval
,如果您不知道输入表达式的来源,则可以引入任意代码。
plt.figure()
numX = np.linspace(-1, 1, 1001)
numY = np.linspace(-1, 1, 1001)
for r in result:
fx = lambdify(x, r[0], "numpy")
fy = lambdify(y, r[1], "numpy")
x_val = fx(numX)
y_val = fy(numY)
if np.shape(x_val) != np.shape(y_val):
if len(np.shape(x_val)) < 1:
x_val = np.ones(len(y_val)) * x_val
else:
y_val = np.ones(len(x_val)) * y_val
plt.plot(x_val, y_val)