Python中的曲线拟合

2 投票
2 回答
5671 浏览
提问于 2025-04-16 12:54

你好,

我有一组频率和功率谱的数据,我需要在对数坐标上绘制功率谱与频率的关系图。完成后,我还需要在这个图上画一条最佳拟合直线。问题是,我在普通坐标上得到了这条线,但当我试图把它叠加到频率-功率谱的图上时,结果图上没有显示出这条线,反而是第一个图的数据点只是位置发生了移动。

而且,如果我用loglog函数在对数坐标上绘制同样的直线,它也不会显示出来。

有没有人能告诉我,我该怎么做才能在对数坐标上显示这条线呢?

我有一个文件,里面有三列数据:频率、功率谱和功率信号。下面是我写的绘制数据和直线的代码片段……

#initialize all variables to 0

#open the data file

while 1:
  ln = datafile.readline()
  if ln:
    data = ln.split()
    x = float(n)
    y = float(data[0])
    z = float(data[1])
    xval.append(float(n))
    yval.append(y)
    zval.append(z)
    n += 1
    sum_z += z
    sum_y += y
    sum_y_squared += y*y
    sum_yz += y*z
  else:
    break
datafile.close()

# calculate slope and intercept using formulae
for num in xval:
    res = intercept + slope*num
    line.append(res)

#Plot data
pylab.figure(0)
matplotlib.pylab.loglog(yval,zval)

#Plot line
pylab.figure(0)
pylab.plotloglog(line)

2 个回答

2

根据我对你问题的理解,你想在同一个图表上画两条线。一般来说,做法是这样的:

import matplotlib.pyplot as plt

fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot(line1_x, line1_y)
ax.plot(line2_x, line2_y)
ax.set_yscale("log")

首先,你需要把这两条线放在同一个Axes里,这样它们才能出现在同一个图表上。要调整坐标轴的刻度,你可以分别使用set_xscaleset_yscale

另外,我注意到你读取文件的代码写得很糟糕。正如@Bernhard在他的回答中提到的,试试用numpy.loadtxt。这段代码可以这样写:

data = numpy.loadtxt("data.txt")
n = len(data)
x = numpy.arange(n)
sum_z = sum(data.T[1])
sum_y = sum(data.T[0])
sum_y_squared = sum(data.T[0]**2)
sum_yz = sum(data.T[0]*data.T[1])

这样做应该能给你和你之前循环得到的结果一样,只是写法更简洁。我强烈建议你看看NumPy快速入门教程,里面讲了很多关于numpy数组的很酷的功能。

2

虽然你给出的绘图命令在例子中不太正确,但我想它和你实际做的事情是差不多的。

第二个绘图命令是在不同的x范围内绘图:

loglog(yval,zval) # plot  yval vs zval
loglog(line) #  plots range(0,len(line)) vs line

你有没有检查一下line的值,它们是否合理?这些值和yval、zval在同一个范围内吗?

另外,你可能想用numpy.loadtxt来加载你的数据文件。

撰写回答