gpt4 book ai didi

python - Matplotlib 在动画刷新后连接数据末尾

转载 作者:行者123 更新时间:2023-12-01 09:12:23 24 4
gpt4 key购买 nike

我遇到了类似 this 的问题帖子,但稍微令人沮丧。

我正在使用 matplotlib 从另一个应用程序提供数据的文件中读取数据。由于某种原因,数据的末端仅在动画 (animation.FuncAnimation) 完成第一次刷新后才连接。以下是一些图片:

这是刷新之前的: Pre-Refresh

这是刷新后的: Post-Refresh

关于为什么会发生这种情况有什么想法吗?这是我的代码:

import json
import itertools
import dateutil.parser

import matplotlib.pyplot as plt
import matplotlib.animation as animation
from matplotlib import style
import scipy.signal as sig
import numpy as np
import pylab as plt

sensors = {}
data = []
lastLineReadNum = 0

class Sensor:

def __init__(self, name, points = 0, lastReading = 0):
self.points = points
self.lastReading = lastReading
self.name = name
self.x = []
self.y = []

class ScanResult:
def __init__(self, name, id, rssi, macs, time):
self.name = name
self.id = id
self.rssi = rssi
self.macs = macs
# Is not an integer, but a datetime.datetime
self.time = time

def readJSONFile(filepath):

with open(filepath, "r") as read_file:
global lastLineReadNum
# Load json results into an object that holds important info
for line in itertools.islice(read_file, lastLineReadNum, None):
temp = json.loads(line)
# Only reads the most recent points...
data.append(ScanResult(name = temp["dev_id"],
id = temp["hardware_serial"],
rssi = temp["payload_fields"]["rssis"],
macs = temp["payload_fields"]["macs"],
time = dateutil.parser.parse(temp["metadata"]["time"])))
lastLineReadNum += 1

return data

style.use('fivethirtyeight')
fig = plt.figure()
ax1 = fig.add_subplot(1, 1, 1)

def smooth(y, box_pts):
box = np.ones(box_pts)/box_pts
y_smooth = np.convolve(y, box, mode='same')
return y_smooth

def determineClosestSensor():
global sensors

#sensors.append(Sensor(time = xs3, rssi = ys3))

def determineXAxisTime(scanresult):
return ((scanresult.time.hour * 3600) + (scanresult.time.minute * 60) + (scanresult.time.second)) / 1000.0

def animate(i):
data = readJSONFile(filepath = "C:/python_testing/rssi_logging_json.json")

for scan in data:
sensor = sensors.get(scan.name)

# First time seeing the sensor
if(sensor == None):
sensors[scan.name] = Sensor(scan.name)
sensor = sensors.get(scan.name)
sensor.name = scan.name
sensor.x.append(determineXAxisTime(scan))
sensor.y.append(scan.rssi)

else:
sensor.x.append(determineXAxisTime(scan))
sensor.y.append(scan.rssi)

ax1.clear()

#basic smoothing using nearby averages

#y_smooth3 = smooth(np.ndarray.flatten(np.asarray(sensors.get("sentrius_sensor_3").y)), 1)

for graphItem in sensors.itervalues():
smoothed = smooth(np.ndarray.flatten(np.asarray(graphItem.y)), 1)
ax1.plot(graphItem.x, smoothed, label = graphItem.name, linewidth = 2.0)

ax1.legend()

determineClosestSensor()

fig.suptitle("Live RSSI Graph from Sentrius Sensors", fontsize = 14)


def main():
ani = animation.FuncAnimation(fig, animate, interval = 15000)

plt.show()

if __name__ == "__main__":
main()

最佳答案

据我所知,您正在通过附加到现有数据集来在每个动画步骤中重新生成数据,但这意味着第一步中的最后一个 x 点后面跟着第一个点第二步中的 x 点,导致情节倒带。这显示为连接最后一个数据点与第一个数据点的线;其余数据不变。

animate的相关部分:

def animate(i):
data = readJSONFile(filepath = "C:/python_testing/rssi_logging_json.json")

for scan in data:
sensor = sensors.get(scan.name)

# First time seeing the sensor
if(sensor is None): # always check for None with `is`!
... # stuff here
else:
sensor.x.append(determineXAxisTime(scan)) # always append!
sensor.y.append(scan.rssi) # always append!

... # rest of the stuff here

因此,在每个动画步骤中,您 1.加载相同的JSON文件 2. 将相同的数据附加到由 sensors.get(scan.name) 标识的现有传感器 3. 无需使用 i 即可绘制内容。

首先,您的 animate 自然应该使用索引 i:您正在尝试执行有关步骤 i 的操作。我看不到 i 在任何地方被使用。

其次,您的animate应该尽可能轻量,以获得流畅的动画。在绘图之前加载一次数据,并且仅处理 animate 中的绘图差异。这将涉及将数据作为 i 的函数进行切片或操作。

当然,如果文件确实逐步变化,并且这是动画中的实际动态(即 i 是一个从未使用过的虚拟变量),那么您需要做的就是对每一步中的所有绘图数据进行零初始化。从头开始。然后您将不再看到与数据中这些人为跳跃相对应的线条。但同样,如果您想要一个轻量级的动画,您应该考虑操作现有绘图的基础数据,而不是一直重新绘制所有内容(特别是在调用 ax1.plot 后)将在 Canvas 上保留较早的点,这不是您在动画中通常想要的)。

关于python - Matplotlib 在动画刷新后连接数据末尾,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51547551/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com