【问题标题】:How to smooth the curve in python for a Beginer如何在python中为初学者平滑曲线
【发布时间】:2018-12-19 07:52:21
【问题描述】:

我正在使用以下代码从我的两列原始数据(x=time,y=|float data|)中绘制一条曲线。它绘制的图形是一个粗糙的边缘图。是否有可能对这些数据进行平滑处理?我附上代码、数据和曲线。

from datetime import datetime
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.dates
from matplotlib import style

# changing matplotlib the default style
matplotlib.style.use('ggplot')
#one of {'b', 'g', 'r', 'c', 'm', 'y', 'k', 'w'}
plt.rcParams['lines.linewidth']=1
plt.rcParams['axes.facecolor']='.3'
plt.rcParams['xtick.color']='b'
plt.rcParams['ytick.color']='r'



x,y= np.loadtxt('MaxMin.txt', dtype=str, unpack=True)
x = np.array([datetime.strptime(i, "%H:%M:%S.%f") for i in x])
y = y.astype(float)

# naming the x axis 
plt.xlabel('<------Clock-Time(HH:MM:SS)------>') 
# naming the y axis 
plt.ylabel('Acceleration (m/sq.sec)') 
# giving a title to my graph 
plt.title('Sample graph!')
# plotting the points 
plt.plot(x, y)
# beautify the x-labels
plt.gcf().autofmt_xdate()
#Custom Format
loc = matplotlib.dates.MicrosecondLocator(1000000)
plt.gca().xaxis.set_major_locator(loc)
plt.gca().xaxis.set_major_formatter(matplotlib.dates.DateFormatter('%H:%M:%S'))
# function to show the plot 
plt.show()

我搜索过类似的主题,但它们使用的数学概念让我无法理解。所以我无法确定对我的数据究竟需要做什么。

Generated Graph from RAW data

我还提供了示例数据文件,以便您可以在最后重新构建它。

Get Data File

PS。即使在使用后,我也无法将图表中的线条颜色从默认红色更改

plt.rcParams['lines.color']='g'

虽然在这种情况下这是一个小问题。

**请使用我的代码和数据,看看你的建议是否真的有效,如果可能的话,发布输出图。我是 python 的初学者。所以还不完全熟悉其他人非常明显的东西。 **

【问题讨论】:

  • 数据看起来不按时间顺序排列,因此您可能不需要在点之间添加额外的线条。在绘图之前按时间顺序对输入数据进行排序。
  • 它是基于时间的按时间顺序排序的,否则无法排序。我想知道是否可以使用某种过滤器对其进行平滑处理,或者是否需要应用 SVM 等机器学习工具。因为这些是我看到的术语,但不知道什么对这个数据集有好处。
  • 您希望看到什么输出?就目前而言,这个问题非常广泛,尽管这个例子的完整性非常值得称赞。

标签: python filter fft curve smoothing


【解决方案1】:

输入数据的时间戳错误,原作者在格式化毫秒时应该使用了零填充(%03d)。

[...]
10:27:19.3 9.50560385141
10:27:19.32 9.48882194058
10:27:19.61 9.75936468731
10:27:19.91 9.96021690527
10:27:19.122 9.48972151383
10:27:19.151 9.49265161533
[...]

我们需要先解决这个问题:

x, y = np.loadtxt('MaxMin.txt', dtype=str, unpack=True)

# fix the zero-padding issue
x_fixed = []
for xx in x:
    xs = xx.split(".")
    xs[1] = "0"*(3-len(xs[1])) + xs[1]
    x_fixed.append(xs[0] + '.' + xs[1])

x = np.array([datetime.strptime(i, "%H:%M:%S.%f") for i in x_fixed])
y = y.astype(float)

然后您可以使用平滑内核(例如移动平均线)来平滑数据:

window_len = 3
kernel = np.ones(window_len, dtype=float)/window_len
y_smooth = np.convolve(y, kernel, 'same')

【讨论】:

  • 只有在数据实际上是适当单调的情况下才能对数据进行平滑处理。
  • 它应该已经像这样排序了,因为数据在一段时间内来自传感器。你检查过我分享的数据文件的逻辑了吗?如果满足要求,请发布输出图让我有一个想法。
  • 嗯,不是。
  • 第一列包含格式为 HH:MM:S.msec 的时间戳。并且数据按时间升序排列。
  • 在答案中查看我的评论。编写时间戳数据的代码的人做错了。不过,你可以绕过它。
【解决方案2】:

scipy 模块有一些方法可以通过您的点获得平滑曲线。尝试将其添加到顶部:

from scipy import interpolate

然后在您的 plt.show() 之前添加这些行:

xnew = np.linspace(x.min(), x.max(), 100) 
bspline = interpolate.make_interp_spline(x, y)
y_smoothed = bspline(xnew)
plt.plot(xnew, y_smoothed)

如果您稍微搜索一下scipy.interpolate.make_interp_spline,您可以找到更多关于它的作用的信息。但本质上,它和np.linspace 的组合会生成一堆假数据点来组成一条平滑的曲线。

【讨论】:

  • 我无法添加其他数据进行平滑处理。但是删除现有数据的一部分是可以的。
猜你喜欢
  • 2023-03-04
  • 2018-03-19
  • 2021-10-09
  • 1970-01-01
  • 2021-04-26
  • 2021-05-25
  • 2012-10-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多