[由一个简单的错字引起的胡说八道的问题]

[Nonsense question stemming from a simple typo]

我的困惑只是因为我的代码中有错别字——这里没有什么有趣的东西可以学! 我只是绘制了错误的函数,请参阅我对已接受答案的评论。

下面是一些看似无害的Python代码

import matplotlib.pyplot as plt 
import numpy as np 
  
delta = 0.02    
    
x = np.arange(-10, 10, delta) 
y = np.arange(-10, 10, delta) 
[X, Y] = np.meshgrid(x, y) 
  
fig, ax = plt.subplots() 
  
Z = X**2+2*X*Y+Y**2
# for comparison later use this:
#Z = 3.14*X**2+0.6*Y**2 
  
ax.contour(X, Y, Z)   
ax.set_xlabel('x') 
ax.set_ylabel('y') 
  
plt.show() 

及其输出:

等高线画错了!我正在绘制二次函数的等高线图,等高线应该是椭圆。显示的线不仅仅是看似线,在更大的比例下会变成椭圆。我至少有两个理由这么说:

  1. 这是类似比例的 Wolfram Alpha contour plot of the same function。它显示了应该在那里的省略号。

  2. 我手算了对应的对角线二次型(根据Principal Axis theorem): 就是Z = 3.14*X**2+0.6*Y**2.

此函数首先将给定向量 (X,Y) 旋转一定角度,然后应用代码中使用的函数 Z = X**2+2*X*Y+Y**2。因此,这两个函数的等高线图应该只相差一个旋转。

但是在上面的代码中插入 Z = 3.14*X**2+0.6*Y**2 来代替之前的 Z,会产生一个完美的省略号:

我的问题:

  1. 他的行为有何解释?
  2. 如何获得第一个函数的准确等高线图?

matplotlib 等高线图是正确的。

A) 我们可以看一下3D投影:

from mpl_toolkits.mplot3d import Axes3D
import numpy as np
import matplotlib.pyplot as plt

fig = plt.figure(figsize=(10,10))
ax = fig.gca(projection='3d')

delta = 2  
    
x = np.arange(-100, 100, delta) 
y = np.arange(-100, 100, delta) 
X, Y = np.meshgrid(x, y)   
  
Z = X**2 + Y**2 + 2*X*Y
ax.plot_surface(X, Y, Z)

plt.show()

示例输出:

是的,平行于 x = -y 的线。

B) 让我们看一下 x+y=a 的数学表示,即 y=a-x

然后是:
z = x² + y² + 2xy
= x² + (a-x)² + 2x(a-x)
= x² + a² - 2ax + x² + 2ax - 2x²
= a²

这就是我们在曲面图和等高线图中看到的 - 对于平行于 x=-y 的线,z 值独立于 x (或 y)并且仅取决于 a(正负 a 值是对称的)。

C) 显然,x²+2xy+ay²a 的等高线图不同(如您所料)。但是因为我们可以,让我们添加这个小例子:

import matplotlib.pyplot as plt 
import numpy as np 
  
delta = 0.02  
    
x = np.arange(-10, 10, delta) 
y = np.arange(-10, 10, delta) 
X, Y = np.meshgrid(x, y) 
  
fig, axes = plt.subplots(3, 3, figsize=(10,10)) 
  
Z = X**2 + Y**2 + 3*Y*X
# for comparison later use this:
#Z = 3.14*X**2+0.6*Y**2 

for i, ax in enumerate(axes.flatten()):
    a=i-2
    Z = X**2 + a* Y**2 + 2*X*Y
    cs = ax.contour(X, Y, Z)
    ax.clabel(cs, inline=True, fontsize=10)
    ax.set_title("x²+2xy+ay² for a="+str(a))
  
plt.tight_layout()
plt.show() 

示例输出: