2025-01-02 12:48:11 +08:00
|
|
|
|
import json
|
|
|
|
|
import math
|
|
|
|
|
import pandas as pd
|
|
|
|
|
import matplotlib.pyplot as plt
|
|
|
|
|
from matplotlib import rcParams
|
|
|
|
|
|
|
|
|
|
# 设置字体为 SimHei(黑体)或其他支持中文的字体
|
|
|
|
|
rcParams['font.sans-serif'] = ['SimHei'] # 或者 ['Microsoft YaHei']
|
|
|
|
|
rcParams['axes.unicode_minus'] = False # 解决负号显示问题
|
|
|
|
|
|
|
|
|
|
# 指定 JSON 文件的路径
|
2025-01-06 09:12:40 +08:00
|
|
|
|
file_path = r"C:\Users\10561\Desktop\2025-01-06_应用日志.json"
|
2025-01-02 12:48:11 +08:00
|
|
|
|
|
|
|
|
|
# 打开并读取 JSON 文件
|
|
|
|
|
with open(file_path, 'r', encoding='utf-8') as file:
|
|
|
|
|
data = json.load(file)
|
|
|
|
|
|
|
|
|
|
# 提取指定设备和类型的日志片段
|
|
|
|
|
log_ones = []
|
|
|
|
|
start_idx = -1
|
|
|
|
|
for idx, one in enumerate(data):
|
|
|
|
|
if 'Acar' == one['设备'] and '2' == one['类型']:
|
|
|
|
|
if 1 == one['位置'] and 1 == one['方向']:
|
|
|
|
|
start_idx = idx
|
|
|
|
|
continue
|
|
|
|
|
if 8 == one['位置'] and 2 == one['方向']:
|
|
|
|
|
if start_idx == -1:
|
|
|
|
|
continue
|
|
|
|
|
log_ones.append(data[start_idx:idx+1])
|
|
|
|
|
start_idx = -1
|
2025-01-06 09:12:40 +08:00
|
|
|
|
print(idx)
|
2025-01-06 09:29:02 +08:00
|
|
|
|
|
2025-01-02 12:48:11 +08:00
|
|
|
|
# 筛选出只有 "Acar" 的日志片段
|
|
|
|
|
log_ones_new = []
|
|
|
|
|
for one in log_ones:
|
|
|
|
|
one_only_car = [one_one for one_one in one if 'Acar' == one_one['设备']]
|
|
|
|
|
log_ones_new.append(one_only_car)
|
2025-01-06 09:12:40 +08:00
|
|
|
|
[print(o) for o in log_ones_new]
|
2025-01-02 12:48:11 +08:00
|
|
|
|
|
|
|
|
|
# 计算时间差
|
|
|
|
|
time_diffs = []
|
|
|
|
|
for one_one in log_ones_new:
|
|
|
|
|
df = pd.DataFrame(one_one)
|
|
|
|
|
df['时间戳'] = pd.to_numeric(df['时间戳'])
|
|
|
|
|
df['时间差'] = df['时间戳'].diff()
|
|
|
|
|
time_diff = df[['位置', '方向', '时间差']].dropna().reset_index(drop=True)
|
|
|
|
|
time_diffs.append(time_diff)
|
2025-01-06 09:29:02 +08:00
|
|
|
|
|
|
|
|
|
# 找出行数最多的时间差数据集,以它的 (位置-方向) 组合作为标准 X 轴标签
|
|
|
|
|
max_len_dataset = max(time_diffs, key=len)
|
|
|
|
|
all_x_labels = max_len_dataset['位置'].astype(str) + '-' + max_len_dataset['方向'].astype(str)
|
|
|
|
|
|
|
|
|
|
# 标准化所有数据集(没有对应的“位置-方向”就补 0)
|
2025-01-02 12:48:11 +08:00
|
|
|
|
standardized_time_diffs = []
|
|
|
|
|
for time_diff in time_diffs:
|
|
|
|
|
time_diff['位置-方向'] = time_diff['位置'].astype(str) + '-' + time_diff['方向'].astype(str)
|
|
|
|
|
standardized_time_diff = []
|
|
|
|
|
|
2025-01-06 09:29:02 +08:00
|
|
|
|
data_idx = 0
|
|
|
|
|
last_is_null = 0
|
|
|
|
|
for idx_label, label in enumerate(all_x_labels):
|
|
|
|
|
row = time_diff.iloc[data_idx] if data_idx < len(time_diff) else None
|
|
|
|
|
if row is not None and row['位置-方向'] == label:
|
|
|
|
|
# 命中当前 label
|
|
|
|
|
if last_is_null == 1:
|
|
|
|
|
last_is_null = 0
|
|
|
|
|
standardized_time_diff.append(0) # 这里保持你原先的逻辑,先补 0,后面再统一填充
|
2025-01-02 12:48:11 +08:00
|
|
|
|
else:
|
2025-01-06 09:29:02 +08:00
|
|
|
|
standardized_time_diff.append(row['时间差'])
|
|
|
|
|
data_idx += 1
|
2025-01-02 12:48:11 +08:00
|
|
|
|
else:
|
2025-01-06 09:29:02 +08:00
|
|
|
|
# 没有命中当前 label
|
2025-01-02 12:48:11 +08:00
|
|
|
|
standardized_time_diff.append(0)
|
2025-01-06 09:29:02 +08:00
|
|
|
|
last_is_null = 1
|
|
|
|
|
|
2025-01-02 12:48:11 +08:00
|
|
|
|
standardized_time_diffs.append(standardized_time_diff)
|
|
|
|
|
|
2025-01-06 09:29:02 +08:00
|
|
|
|
# -------- 新增:填充 0 的函数 --------
|
|
|
|
|
def fill_zeros_with_nearest(values):
|
|
|
|
|
"""
|
|
|
|
|
将列表中的 0 用最近的非 0 值进行填充
|
|
|
|
|
(先前向填充,再后向填充)
|
|
|
|
|
"""
|
|
|
|
|
# 前向填充
|
|
|
|
|
for i in range(1, len(values)):
|
|
|
|
|
if values[i] == 0 and values[i-1] != 0:
|
|
|
|
|
values[i] = values[i-1]
|
|
|
|
|
# 后向填充
|
|
|
|
|
for i in range(len(values) - 2, -1, -1):
|
|
|
|
|
if values[i] == 0 and values[i+1] != 0:
|
|
|
|
|
values[i] = values[i+1]
|
|
|
|
|
return values
|
2025-01-02 12:48:11 +08:00
|
|
|
|
|
|
|
|
|
# 创建子图的行列数(自动计算)
|
|
|
|
|
num_plots = len(all_x_labels)
|
|
|
|
|
rows = math.ceil(math.sqrt(num_plots)) # 行数
|
2025-01-06 09:29:02 +08:00
|
|
|
|
cols = math.ceil(num_plots / rows) # 列数
|
2025-01-02 12:48:11 +08:00
|
|
|
|
|
|
|
|
|
# 创建大画布
|
|
|
|
|
fig, axes = plt.subplots(rows, cols, figsize=(16, 12))
|
|
|
|
|
axes = axes.flatten() # 将子图数组展平,方便迭代
|
|
|
|
|
|
|
|
|
|
# 在每个子图中绘制折线
|
|
|
|
|
for idx, label in enumerate(all_x_labels):
|
|
|
|
|
# 获取当前 "位置-方向" 对应的 y 值
|
2025-01-06 09:29:02 +08:00
|
|
|
|
y_values = []
|
|
|
|
|
for time_diff in standardized_time_diffs:
|
|
|
|
|
# 如果下标越界就补 0
|
|
|
|
|
y_values.append(time_diff[idx] if idx < len(time_diff) else 0)
|
|
|
|
|
|
|
|
|
|
# -------- 在绘图前,对 y_values 做一次非 0 值填充 --------
|
|
|
|
|
y_values_filled = fill_zeros_with_nearest(y_values)
|
2025-01-02 12:48:11 +08:00
|
|
|
|
|
|
|
|
|
# 绘制当前子图
|
|
|
|
|
ax = axes[idx]
|
|
|
|
|
ax.plot(
|
2025-01-06 09:29:02 +08:00
|
|
|
|
range(len(y_values_filled)),
|
|
|
|
|
y_values_filled,
|
|
|
|
|
marker='o',
|
2025-01-02 12:48:11 +08:00
|
|
|
|
)
|
2025-01-06 09:29:02 +08:00
|
|
|
|
ax.set_ylim(0, 10000)
|
|
|
|
|
|
2025-01-02 12:48:11 +08:00
|
|
|
|
|
|
|
|
|
# 设置标题和轴标签
|
|
|
|
|
ax.set_title(f'{label} 的时间差折线图', fontsize=10)
|
|
|
|
|
ax.set_xlabel('标准化时间差数据集', fontsize=8)
|
|
|
|
|
ax.set_ylabel('时间差 (ms)', fontsize=8)
|
2025-01-06 09:29:02 +08:00
|
|
|
|
ax.set_xticks(range(len(y_values_filled)))
|
|
|
|
|
ax.set_xticklabels(
|
|
|
|
|
[f'TimeDiff {i+1}' for i in range(len(y_values_filled))],
|
|
|
|
|
fontsize=6,
|
|
|
|
|
rotation=45
|
|
|
|
|
)
|
2025-01-02 12:48:11 +08:00
|
|
|
|
ax.grid(axis='y', linestyle='--', alpha=0.7)
|
|
|
|
|
|
|
|
|
|
# 删除多余的子图(如果子图数量多于折线图数量)
|
|
|
|
|
for ax in axes[num_plots:]:
|
|
|
|
|
fig.delaxes(ax)
|
|
|
|
|
|
|
|
|
|
# 调整布局
|
|
|
|
|
plt.tight_layout()
|
2025-01-06 09:29:02 +08:00
|
|
|
|
plt.show()
|