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

vmdwslir  于 2023-04-12  发布在  其他
关注(0)|答案(1)|浏览(132)

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

# 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分的平均值。但是,我不愿意这样做,因为感觉像是篡改数据。
使用matplotlib;
我迭代的一个解决方案是使用**make_interp_spline()**手动 * 平滑 * 数据曲线。
这里是我使用https://data.world/argoolsbee/spacex-launch-telemetry/workspace/file?filename=CRS-11+raw.json的数据的链接。你可以使用任何这些文件,它们都与此代码一起工作。
我想先看看我的逻辑是否有错误,然后再用手梳理数据。

xmakbtuz

xmakbtuz1#

有很多方法可以做到这一点。实际上,numpy有一些内置的函数来制作1d导数,这可能对你的问题非常简单,请参阅:Numpy.gradient
除此之外,根据您的计算结果,您可以始终使用高斯滤波器“平滑”您的数据,例如,scipy也有一个内置函数来完成此操作,请参阅:scipy.ndimage.gaussian_filter1d
最后,但并非最不重要的是,如果您认为原始数据上的数据变化可能是突然的,因为它们缺乏分辨率,但您信任数据,您可以始终使用插值数据在点之间生成数据,scipy也有一个内置函数,请参阅:scipy.interpolate.interp1d
所以基本上有很多方式来回答这个问题,这些功能的组合也值得一试。
希望这对你有用。

相关问题