如何从我的计算中创建更均匀的数据曲线?



我正试图从火箭发射中获取原始数据并计算各种变量。我计算的速度非常不稳定,使得它无法读取,也无法用于进一步的计算。我正在寻找输入是否我的数据是坏的,我的代码是垃圾,或者一种方法来平滑图而不丢失我的大部分数据。

输出图


# Essa Hattar
# essa.hattar@wmich.edu
# the purpose of this code is to extract rocket data from a json file and graph its variables
import matplotlib.pyplot as plt
import numpy as np
from scipy.interpolate import make_interp_spline
import json
# set folders to pull from file
time = []
total_speed = []  # NOTE: turns out "velocity" is total SPEED not vertical velocity
altitude = []

def file_name():
while True:
json_name = input('Enter the json file name: ')
try:
data = open((json_name + '.json'), 'r')
data.close()
return json_name
except FileNotFoundError:
print(f'The file name {json_name}.json does not exist')

def extract_data(json_name):
data = open((json_name + '.json'), 'r')
# for every line in file
for line in data:
line_dict = json.loads(line)
# sets data from dict into folders
time.append(line_dict.get('time'))
total_speed.append(line_dict.get('velocity'))
altitude.append(line_dict.get('altitude'))
# close file b/c not needed anymore
data.close()
return time, total_speed, altitude

def calc_vert_velocity(time, altitude):
# velocity == change in distance/ time
velocity = [0]
time_v = [0]  # time and velocity folder need to be same length for graph, so I need a new time folder
# these are all the "start" variables that I will refer too
time_last = 0
altitude_last = 0
for i in range(len(time)):
if altitude_last != altitude[i]:
# calc
velocity_temp = (altitude[i] - altitude_last) / (time[i] - time_last)
# velocity_temp *= 1000  # convert to meters
velocity_temp = round(velocity_temp, 2)
# append folder
velocity.append(velocity_temp)
time_v.append(time[i])
# set condition variables
time_last = time[i]
altitude_last = altitude[i]
return velocity, time_v

def calc_acceleration(time_v, velocity):
pass

def show_graph(json_name, time, altitude, velocity, time_v):
plt.figure(figsize=(10, 5))

# altitude/time
plt.subplot(121)
plt.plot(time, altitude, 'g')
plt.title('Altitude/Time')
plt.xlabel('Seconds')
plt.ylabel('Km')

# velocity/time
plt.subplot(122)
# here down is with spline
x = np.array(time_v)
y = np.array(velocity)

X_Y_Spline = make_interp_spline(x, y)
# Returns evenly spaced numbers
# over a specified interval.
X_ = np.linspace(x.min(), x.max(), 200)
Y_ = X_Y_Spline(X_)
plt.plot(X_, Y_, 'b')
# here up is with spline
"""
plt.plot(time_v, velocity, 'b', linewidth=.5)  # without spline
"""
plt.title('Velocity/Time')
plt.xlabel('Seconds')
plt.ylabel('Km/s')

plt.suptitle(f'{json_name} Telemetry')
plt.show()

def main():
# get file name from user
json_name = file_name()
time, total_speed, altitude = extract_data(json_name)
velocity, time_v = calc_vert_velocity(time, altitude)
show_graph(json_name, time, altitude, velocity, time_v)

main()

calc_vert_velocity ()

;我通过只计算测量高度变化时的速度使数据更具可读性。这从数据中删除了许多不必要的零。我已经试着用不同的形式重写了这个方程。

我正在考虑计算一组3到5分的平均值。但是,我不愿意这样做,因为它感觉像是数据篡改。

与<<p> strong> matplotlib ;我迭代的一个解决方案是使用make_interp_spline()手动平滑数据曲线。

这是我正在使用的数据的链接https://data.world/argoolsbee/spacex-launch-telemetry/workspace/file?filename=CRS-11 + raw.json。您可以使用这些文件中的任何一个,它们都与此代码一起工作。

在我手工梳理数据之前,我想看看我的逻辑是否有错误。

有很多方法可以做到这一点。实际上numpy有一些内置的函数来生成1d导数,这可以很直接地解决你的问题,参见:numpy .gradient.

除此之外,根据你的计算,你总是可以"平滑"。例如,scipy有一个内置的函数来做这件事,参见:scipy.ndimage.gaussian_filter1d.

最后,但并非最不重要的是,如果您认为原始数据上的数据变化可能是突然的,因为它们缺乏分辨率,但您相信数据,您可以始终使用插值数据在您的点之间生成数据,scipy也有一个内置函数,请参阅:scipy.interpolate.interp1d.

所以基本上有很多方式来回答这个问题,这些功能的组合也值得一试。

希望这对你有用。

最新更新