192 lines
6.6 KiB
Python
192 lines
6.6 KiB
Python
import matplotlib.pyplot as plt
|
||
from latencyData import LatencyData
|
||
from latencyArgs import get_args
|
||
import logging
|
||
|
||
|
||
def plot_delay_histogram_with_ci(l: LatencyData, save_to_file=True, show_plot=False, title="default"):
|
||
"""
|
||
Универсальный скрипт для построения гистограммы с доверительным интервалом
|
||
"""
|
||
try:
|
||
plt.rcParams.update({'font.size': 18})
|
||
# Создание гистограммы
|
||
plt.figure(figsize=(14, 8))
|
||
n_bins = min(30, len(l.delays) // 5)
|
||
|
||
n, bins, patches = plt.hist(l.delays, bins=n_bins, alpha=0.7, color='steelblue',
|
||
edgecolor='black', linewidth=0.5, density=False)
|
||
|
||
plt.xlabel('Задержка (мс)')
|
||
plt.ylabel('Частота')
|
||
plt.title(f'Распределение задержек на обработку нажатия мыши {title} (n={len(l.delays)}, CI={l.confidence_level*100}%)',
|
||
fontsize=14, fontweight='bold')
|
||
plt.grid(True, alpha=0.3)
|
||
|
||
l.mean_delay = float(l.mean_delay)
|
||
l.median_delay = float(l.median_delay)
|
||
# Добавление статистических линий
|
||
plt.axvline(l.mean_delay, color='red', linestyle='-', linewidth=2,
|
||
label=f'Среднее ({l.mean_delay:.1f} мс)')
|
||
plt.axvline(l.median_delay, color='green', linestyle='-', linewidth=2,
|
||
label=f'Медиана ({l.median_delay:.1f} мс)')
|
||
|
||
# Добавление доверительного интервала
|
||
plt.axvspan(l.ci_lower, l.ci_upper, alpha=0.2, color='yellow',
|
||
label=f'ДИ {l.confidence_level*100}%: [{l.ci_lower:.1f}, {l.ci_upper:.1f}] мс')
|
||
|
||
# Вертикальные линии для границ доверительного интервала
|
||
plt.axvline(l.ci_lower, color='orange',
|
||
linestyle='--', linewidth=1, alpha=0.7)
|
||
plt.axvline(l.ci_upper, color='orange',
|
||
linestyle='--', linewidth=1, alpha=0.7)
|
||
|
||
plt.legend(loc='upper right')
|
||
plt.tight_layout()
|
||
|
||
# Сохранение в файл
|
||
if save_to_file:
|
||
output_file = f'{get_args().img_prefix}/delay_distribution_{title}_ci_{int(l.confidence_level*100)}.png'
|
||
plt.savefig(output_file, dpi=300, bbox_inches='tight')
|
||
print(f"\n✓ Гистограмма сохранена как: {output_file}")
|
||
|
||
# Показ графика
|
||
if show_plot:
|
||
plt.show()
|
||
else:
|
||
plt.close()
|
||
|
||
print("\n✓ Анализ завершен успешно")
|
||
|
||
return {
|
||
'data': l.delays,
|
||
'mean': l.mean_delay,
|
||
'median': l.median_delay,
|
||
'std': l.std_delay,
|
||
'ci_lower': l.ci_lower,
|
||
'ci_upper': l.ci_upper,
|
||
'confidence_level': l.confidence_level
|
||
}
|
||
except Exception as e:
|
||
print(f"✗ Ошибка: {e}")
|
||
return None
|
||
|
||
|
||
def plot_horizontal_hist_with_ci(latencies: dict, colors: dict, labels: dict, save_to_file=True, show_plot=True, title="default"):
|
||
"""
|
||
Parameters
|
||
----------
|
||
latencies: dict
|
||
key is a filename, value is a latencyData object
|
||
|
||
colors: dict
|
||
key is a filename, value is string in format tab:<color>
|
||
|
||
labels: dict
|
||
key is a filename, value is a string label
|
||
|
||
"""
|
||
plt.rcParams.update({'font.size': 18})
|
||
# Создание гистограммы
|
||
fig, ax = plt.subplots(figsize=(12, 6))
|
||
|
||
keys = latencies.keys()
|
||
values = latencies.values()
|
||
|
||
medians = [i.mean_delay for i in values]
|
||
errors = [i.err for i in values]
|
||
y_idx = range(len(keys))
|
||
logging.info(f"medians={medians}; errors={errors}")
|
||
# sorting of all arrays to have same order of elements
|
||
bar_colors = [colors[key] for key in keys]
|
||
bar_labels = [labels[key] for key in keys]
|
||
bar_mlabels = []
|
||
for key in keys:
|
||
bar_mlabels.append(
|
||
f"{latencies[key].mean_delay:.5g}±{latencies[key].err:.3g}")
|
||
|
||
logging.info(bar_mlabels)
|
||
cont = ax.barh(y_idx, medians, xerr=errors,
|
||
color=bar_colors, capsize=15, align='center')
|
||
ax.bar_label(cont, labels=bar_mlabels, label_type='center')
|
||
logging.info(f"y_idx={y_idx}; bar_labels={bar_labels}")
|
||
ax.set_yticks(y_idx, bar_labels)
|
||
ax.set_xlabel('Задержка (мс)')
|
||
fig.tight_layout()
|
||
|
||
if show_plot:
|
||
plt.show()
|
||
else:
|
||
plt.close()
|
||
|
||
if save_to_file:
|
||
fig.savefig(f'{get_args().img_prefix}/delay_dist_overall_{title}')
|
||
|
||
|
||
def plot_point_cloud(latencies: dict,
|
||
colors: dict,
|
||
labels: dict,
|
||
dT: float,
|
||
hlines=dict,
|
||
save_to_file=True,
|
||
show_plot=True,
|
||
title="default"):
|
||
"""
|
||
Parameters
|
||
----------
|
||
latencies: dict
|
||
key is a filename, value is a latencyData object
|
||
|
||
colors: dict
|
||
key is a filename, value is string in format tab:<color>
|
||
|
||
labels: dict
|
||
key is a filename, value is a string label
|
||
|
||
"""
|
||
|
||
plt.rcParams.update({'font.size': 16})
|
||
# Создание гистограммы
|
||
fig, ax = plt.subplots(figsize=(14, 10))
|
||
|
||
keys = latencies.keys()
|
||
values = latencies.values()
|
||
|
||
medians = [i.mean_delay for i in values]
|
||
|
||
# sorting of all arrays to have same order of elements
|
||
point_labels = [labels[key] for key in keys]
|
||
point_colors = [colors[key] for key in keys]
|
||
point_xminall = min(len(value.delays) for value in values)
|
||
point_values = [value.delays[:point_xminall] for value in values]
|
||
point_x = list(range(point_xminall))
|
||
point_x = [float(x) * dT for x in point_x]
|
||
point_ld = [value for value in values]
|
||
for i in range(len(point_values)):
|
||
ax.plot(point_x,
|
||
point_values[i],
|
||
color=point_colors[i],
|
||
label=point_labels[i],
|
||
marker='o',
|
||
linestyle='None')
|
||
ax.axhline(y=medians[i],
|
||
color=point_colors[i],
|
||
linestyle='--')
|
||
ax.axhspan(point_ld[i].ci_lower,
|
||
point_ld[i].ci_upper,
|
||
alpha=0.2,
|
||
color=point_colors[i])
|
||
ax.legend(ncol=3, bbox_to_anchor=(0.85, 1.15), fancybox=True)
|
||
ax.set_xlabel('Время (секунды)')
|
||
ax.set_ylabel('Задержка (мс)')
|
||
|
||
fig.tight_layout()
|
||
|
||
if show_plot:
|
||
plt.show()
|
||
else:
|
||
plt.close()
|
||
|
||
if save_to_file:
|
||
fig.savefig(f'{get_args().img_prefix}/delay_dist_cloud_{title}')
|