ZeroDivisionError: 代码中的表面绘图出现浮点除零错误

2 投票
1 回答
4992 浏览
提问于 2025-04-18 11:27

我有一段代码用来生成一个表面图。但是它出现了“除以零”的错误。我搞不清楚哪里出了问题。谢谢。

import pylab, csv
import numpy
from mayavi.mlab import *

def getData(fileName):
    try:
        data = csv.reader(open(fileName,'rb'))
    except:
        print 'File not found'
    else:
        data = [[float(row[0]), float(row[1]),float(row[2])] for row in data]
        x = [row[0] for row in data]
        y = [row[1] for row in data]
        z = [row[2] for row in data]
    return (x, y, z)

def plotData(fileName):
    xVals, yVals, zVals = getData(fileName)
    xVals = pylab.array(xVals)   
    yVals = pylab.array(yVals)
    zVals = (pylab.array(zVals)*10**3)
    x, y = numpy.mgrid[-0.5:0.5:0.001, -0.5:0.5:0.001]  
    s = surf(x, y, zVals)
    return s

plotData('data')   

1 个回答

0

如果我理解代码没错的话,mayavi.mlab.surf中的zVals有问题。

根据这个函数的说明,s是一个高度矩阵,也就是一个二维数组,第一维的索引表示x坐标,第二维的索引表示y坐标。 但是你的文件读取器似乎返回的是一个一维向量,而不是一个数组。

不过,这可能不是最棘手的问题。你的文件里似乎包含了x、y和z坐标的三元组。只有当文件中的x和y坐标形成一个规则的方形网格时,你才能使用mayavi.mlab.surf。如果是这样的话,你只需要恢复这个网格,并把三个部分都整理成漂亮的二维数组。如果文件中的点是按已知顺序排列的,那就简单多了;如果不是,那就比较麻烦。

也许你可以先试试mayavi.mlab.points3d(xVals, yVals, zVals)。这样可以让你对数据有个整体的印象。(或者如果你对数据已经了解得更多,可以通过编辑你的问题来给我们更多提示!)


为了让你了解可能更符合Python风格的写法,你的代码被重写了(并且surf被替换)如下:

import mayavi.mlab as ml
import numpy

def plot_data(filename):
    data = numpy.loadtxt(filename)
    xvals = data[:,0]
    yvals = data[:,1]
    zvals = data[:,2] * 1000.
    return ml.points3d(x, y, z)

plot_data('data')   

(主要的变化包括:使用numpy.loadtxt,去掉pylab命名空间,不使用import *,不使用驼峰命名法的变量或函数名。想了解更多,可以查看PEP 8。)


如果你只需要查看表面的形状,并且文件中的数据是按行排列的,每行的数据点数量相同(也就是列数固定),那么你可以使用:

import mayavi.mlab as ml
import numpy
importt matplotlib.pyplot as plt

# whatever you have as the number of points per row
columns = 13

data = numpy.loadtxt(filename)

# draw the data points into a XY plane to check that they really for a rectangular grid:
plt.plot(data[:,0], data[:,1])

# draw the surface
zvals = data[:,2].reshape(-1,columns)
ml.surf(zvals, warp_scale='auto')

如你所见,这段代码可以让你检查你的值是否真的在正确的网格中。它并没有检查这些值的顺序是否正确,但至少你可以看到它们形成了一个不错的网格。此外,你需要手动输入列数。关键字warp_scale负责表面缩放,这样看起来就会比较合理。

撰写回答