Matplotlib 等高线图不工作

3 投票
3 回答
3810 浏览
提问于 2025-04-16 22:30

我正在尝试绘制蝙蝠侠方程的图形。如果能用sympy或matplotlib来解决就太好了(sage不太好用,因为我在用Windows)。问题是,如果我注释掉某些部分,图形的一部分会出现,但如果我加上所有的F *=部分,图就变成空白了。

import matplotlib.pyplot
from numpy import arange
from numpy import meshgrid
from numpy import sqrt
from numpy import real

delta = 0.01
xrange = arange(-7.0, 7.0, delta)
yrange = arange(-3.0, 3.0, delta)
x, y = meshgrid(xrange,yrange)

F = 1
F *= (((x/7) ** 2) * sqrt(abs(abs(x) - 3)/(abs(x) - 3)) + ((y / 3) ** 2) * sqrt(abs(y + (3 * sqrt(33)) / 7)/(y + (3 * sqrt(33)) / 7)) - 1)
F *= (abs(x/2) - ((3 * sqrt(33) - 7)/112) * x**2 - 3 + sqrt(1 - (abs(abs(x) - 2) - 1) ** 2 ) - y)
F *= (9 * sqrt(abs((abs(x) - 1) * (abs(x) - 3/4))/((1 - abs(x)) * (abs(x) - 3/4))) - 8 * abs(x) - y)
F *= (3 * abs(x) + 0.75 * sqrt(abs((abs(x) - 3/4) * (abs(x) - 1/2))/((3/4 - abs(x)) * (abs(x) - 1/2))) - y)
F *= ((9/4) * sqrt(abs((x - 1/2) * (x + 1/2))/((1/2 - x) * (1/2 + x))) - y)
F *= ((6 * sqrt(10)) / 7 + (3/2 - abs(x)/2) * sqrt(abs(abs(x) - 1)/(abs(x) - 1)) - ((6 * sqrt(10))/ 14) * sqrt(4 - (abs(x) - 1) ** 2 ) - y)
G = 0

matplotlib.pyplot.contour(x, y, (F - G), [0])
matplotlib.pyplot.show()

这是怎么回事呢?如果某个乘数的值是零,那么无论我加上其他什么乘数,结果应该还是零才对。

蝙蝠侠方程的来源:http://www.reddit.com/r/pics/comments/j2qjc/do_you_like_batman_do_you_like_math_my_math/

3 个回答

0

我不太明白这个公式是怎么运作的,因为在第一个项里(第一个平方根下面),当绝对值x等于3时,会出现除以零的情况。而在最后一个项里(最后一个平方根下面),当{abs(x)-1}^2大于4时(也就是x大于3或小于-3),会出现虚数。
我是不是漏掉了什么?结果是不是只用到实数部分,除以零的情况是不是被忽略或者近似处理了?

运行这个代码时,我确实看到了很多运行时警告,而且matplotlib可能会完全搞不清楚该用哪些数字(比如NaN和Inf;在最后尝试打印F的时候)。看起来当NaN或Inf的数量相对较少时,它还是能正常工作,这也解释了你能看到图的一部分。
我觉得matplotlib的轮廓图是没问题的,只是对输入数据感到困惑。

0

我知道这听起来可能有点无聊,但你可以先创建一个x值的列表,然后在这些位置上计算“batman”的值,并把结果存储在另一个列表里。你可以定义一个叫“batman”的函数,这个函数会根据你传入的每个x值计算出对应的y值。

然后只需用matplotlib把这些列表画出来就可以了。

编辑:因为你已经创建了numpy数组来存储结果,所以在计算y值的时候可以直接使用这些数组。

9

对于很多点来说,sqrt这个函数的参数是负数,所以最后的结果都是NaN(不是一个数字)。你可以像下面这样画出每个因素的图:

from __future__ import division  # this is important, otherwise 1/2 will be 0
import matplotlib.pyplot
from numpy import arange
from numpy import meshgrid
from numpy import sqrt
from numpy import real


delta = 0.01
xrange = arange(-7.0, 7.0, delta)
yrange = arange(-3.0, 3.0, delta)
x, y = meshgrid(xrange,yrange)

F1 = (((x/7) ** 2) * sqrt(abs(abs(x) - 3)/(abs(x) - 3)) + ((y / 3) ** 2) * sqrt(abs(y + (3 * sqrt(33)) / 7)/(y + (3 * sqrt(33)) / 7)) - 1)
F2 = (abs(x/2) - ((3 * sqrt(33) - 7)/112) * x**2 - 3 + sqrt(1 - (abs(abs(x) - 2) - 1) ** 2 ) - y)
F3 = (9 * sqrt(abs((abs(x) - 1) * (abs(x) - 3/4))/((1 - abs(x)) * (abs(x) - 3/4))) - 8 * abs(x) - y)
F4 = (3 * abs(x) + 0.75 * sqrt(abs((abs(x) - 3/4) * (abs(x) - 1/2))/((3/4 - abs(x)) * (abs(x) - 1/2))) - y)
F5 = ((9/4) * sqrt(abs((x - 1/2) * (x + 1/2))/((1/2 - x) * (1/2 + x))) - y)
F6 = ((6 * sqrt(10)) / 7 + (3/2 - abs(x)/2) * sqrt(abs(abs(x) - 1)/(abs(x) - 1)) - ((6 * sqrt(10))/ 14) * sqrt(4 - (abs(x) - 1) ** 2 ) - y)


for f in [F1,F2,F3,F4,F5,F6]:
    matplotlib.pyplot.contour(x, y, f, [0])
matplotlib.pyplot.show()

结果图:

enter image description here

撰写回答