feat: add multiple graphing functionality and multiple comparison charts

This commit is contained in:
2025-12-11 03:18:33 +00:00
parent daaad57c08
commit 87f797987b
13 changed files with 365 additions and 0 deletions

365
main/graphing_all.py Normal file
View File

@@ -0,0 +1,365 @@
import pandas as pd
import matplotlib.pyplot as plt
import glob
import os
# Find CSV files using glob
def load_latest_csv(pattern):
"""Load the most recent CSV file matching the pattern"""
files = glob.glob(pattern)
if not files:
print(f"Aviso: Nenhum ficheiro encontrado com o padrão '{pattern}'")
return None
# Sort by modification time, get the latest
latest_file = max(files, key=os.path.getmtime)
print(f"A carregar: {latest_file}")
return pd.read_csv(latest_file)
print("="*60)
print("ANÁLISE COMPLETA DE SIMULAÇÃO")
print("="*60)
# Carregar todos os dados
print("\nA procurar ficheiros de análise...")
low = load_latest_csv('analysis/LOW_LOAD_*.csv')
medium = load_latest_csv('analysis/MEDIUM_LOAD_*.csv')
high = load_latest_csv('analysis/HIGH_LOAD_*.csv')
# Check if we have all data
if low is None or medium is None or high is None:
print("\nErro: Ficheiros de análise em falta!")
print("Por favor execute a análise batch primeiro.")
exit(1)
# Create output directory for graphs
os.makedirs('graphs', exist_ok=True)
# Determine the run column name (could be 'Run' or 'Execução')
run_col = 'Run' if 'Run' in low.columns else 'Execução'
print(f"\nColunas disponíveis: {low.columns.tolist()}")
# ==============================================================================
# GRÁFICOS COMPARATIVOS (entre cargas)
# ==============================================================================
print("\n" + "="*60)
print("A GERAR GRÁFICOS COMPARATIVOS")
print("="*60)
# 1. Gráfico: Dwelling Time vs Load
plt.figure(figsize=(10, 6))
dwelling_times = [
low['TempoMédioSistema'].mean(),
medium['TempoMédioSistema'].mean(),
high['TempoMédioSistema'].mean()
]
plt.bar(['Baixa', 'Média', 'Alta'], dwelling_times, color=['green', 'orange', 'red'])
plt.ylabel('Tempo Médio no Sistema (s)')
plt.title('Desempenho do Sistema vs Carga')
plt.xlabel('Cenário de Carga')
plt.grid(axis='y', alpha=0.3)
for i, v in enumerate(dwelling_times):
plt.text(i, v + 1, f'{v:.2f}s', ha='center', va='bottom')
plt.savefig('graphs/dwelling_time_comparison.png', dpi=300, bbox_inches='tight')
print("Gráfico guardado: graphs/dwelling_time_comparison.png")
plt.close()
# 2. Gráfico: Completion Rate vs Load
plt.figure(figsize=(10, 6))
completion_rates = [
low['TaxaConclusão'].mean(),
medium['TaxaConclusão'].mean(),
high['TaxaConclusão'].mean()
]
plt.bar(['Baixa', 'Média', 'Alta'], completion_rates, color=['green', 'orange', 'red'])
plt.ylabel('Taxa de Conclusão (%)')
plt.title('Taxa de Conclusão de Veículos vs Carga')
plt.xlabel('Cenário de Carga')
plt.grid(axis='y', alpha=0.3)
plt.ylim(0, 100)
for i, v in enumerate(completion_rates):
plt.text(i, v + 2, f'{v:.1f}%', ha='center', va='bottom')
plt.savefig('graphs/completion_rate_comparison.png', dpi=300, bbox_inches='tight')
print("Gráfico guardado: graphs/completion_rate_comparison.png")
plt.close()
# 3. Gráfico: Waiting Time vs Load
plt.figure(figsize=(10, 6))
waiting_times = [
low['TempoMédioEspera'].mean(),
medium['TempoMédioEspera'].mean(),
high['TempoMédioEspera'].mean()
]
plt.bar(['Baixa', 'Média', 'Alta'], waiting_times, color=['green', 'orange', 'red'])
plt.ylabel('Tempo Médio de Espera (s)')
plt.title('Tempo Médio de Espera vs Carga')
plt.xlabel('Cenário de Carga')
plt.grid(axis='y', alpha=0.3)
for i, v in enumerate(waiting_times):
plt.text(i, v + 1, f'{v:.2f}s', ha='center', va='bottom')
plt.savefig('graphs/waiting_time_comparison.png', dpi=300, bbox_inches='tight')
print("Gráfico guardado: graphs/waiting_time_comparison.png")
plt.close()
# 4. Gráfico: Summary Statistics (comparativo)
fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(2, 2, figsize=(14, 10))
loads = ['Baixa', 'Média', 'Alta']
# Vehicles generated
ax1.bar(loads, [low['VeículosGerados'].mean(), medium['VeículosGerados'].mean(), high['VeículosGerados'].mean()], color=['green', 'orange', 'red'])
ax1.set_title('Veículos Gerados')
ax1.set_ylabel('Quantidade')
ax1.grid(axis='y', alpha=0.3)
# Vehicles completed
ax2.bar(loads, [low['VeículosCompletados'].mean(), medium['VeículosCompletados'].mean(), high['VeículosCompletados'].mean()], color=['green', 'orange', 'red'])
ax2.set_title('Veículos Concluídos')
ax2.set_ylabel('Quantidade')
ax2.grid(axis='y', alpha=0.3)
# Min/Max dwelling time
x = range(3)
width = 0.35
ax3.bar([i - width/2 for i in x], [low['TempoMínimoSistema'].mean(), medium['TempoMínimoSistema'].mean(), high['TempoMínimoSistema'].mean()], width, label='Mín', color='lightblue')
ax3.bar([i + width/2 for i in x], [low['TempoMáximoSistema'].mean(), medium['TempoMáximoSistema'].mean(), high['TempoMáximoSistema'].mean()], width, label='Máx', color='darkblue')
ax3.set_title('Tempo no Sistema Mín/Máx')
ax3.set_ylabel('Tempo (s)')
ax3.set_xticks(x)
ax3.set_xticklabels(loads)
ax3.legend()
ax3.grid(axis='y', alpha=0.3)
# Performance summary
metrics = ['Tempo no\nSistema', 'Tempo de\nEspera', 'Taxa de\nConclusão']
low_vals = [low['TempoMédioSistema'].mean(), low['TempoMédioEspera'].mean(), low['TaxaConclusão'].mean()]
med_vals = [medium['TempoMédioSistema'].mean(), medium['TempoMédioEspera'].mean(), medium['TaxaConclusão'].mean()]
high_vals = [high['TempoMédioSistema'].mean(), high['TempoMédioEspera'].mean(), high['TaxaConclusão'].mean()]
x = range(len(metrics))
width = 0.25
ax4.bar([i - width for i in x], low_vals, width, label='Baixa', color='green')
ax4.bar(x, med_vals, width, label='Média', color='orange')
ax4.bar([i + width for i in x], high_vals, width, label='Alta', color='red')
ax4.set_title('Resumo de Desempenho')
ax4.set_xticks(x)
ax4.set_xticklabels(metrics)
ax4.legend()
ax4.grid(axis='y', alpha=0.3)
plt.tight_layout()
plt.savefig('graphs/summary_statistics.png', dpi=300, bbox_inches='tight')
print("Gráfico guardado: graphs/summary_statistics.png")
plt.close()
# ==============================================================================
# GRÁFICOS INDIVIDUAIS POR CARGA
# ==============================================================================
def generate_individual_graphs(data, load_type, load_name, color):
"""Generate detailed graphs for a specific load type"""
print(f"\n{'='*60}")
print(f"A GERAR GRÁFICOS - CARGA {load_name.upper()}")
print("="*60)
# 1. Gráfico: Run-by-Run Dwelling Time
plt.figure(figsize=(12, 6))
plt.plot(data[run_col], data['TempoMédioSistema'], marker='o', color=color, linewidth=2, markersize=6)
plt.fill_between(data[run_col], data['TempoMínimoSistema'], data['TempoMáximoSistema'], alpha=0.2, color=color)
plt.ylabel('Tempo no Sistema (s)')
plt.xlabel('Número da Execução')
plt.title(f'Tempo no Sistema por Execução - Carga {load_name}')
plt.grid(alpha=0.3)
plt.legend(['Média', 'Intervalo Min-Max'])
plt.savefig(f'graphs/{load_type.lower()}_dwelling_time_runs.png', dpi=300, bbox_inches='tight')
print(f"Gráfico guardado: graphs/{load_type.lower()}_dwelling_time_runs.png")
plt.close()
# 2. Gráfico: Run-by-Run Completion Rate
plt.figure(figsize=(12, 6))
plt.plot(data[run_col], data['TaxaConclusão'], marker='o', color=color, linewidth=2, markersize=6)
plt.axhline(y=data['TaxaConclusão'].mean(), color='black', linestyle='--', label=f'Média: {data["TaxaConclusão"].mean():.1f}%')
plt.ylabel('Taxa de Conclusão (%)')
plt.xlabel('Número da Execução')
plt.title(f'Taxa de Conclusão por Execução - Carga {load_name}')
plt.ylim(0, 105)
plt.grid(alpha=0.3)
plt.legend()
plt.savefig(f'graphs/{load_type.lower()}_completion_rate_runs.png', dpi=300, bbox_inches='tight')
print(f"Gráfico guardado: graphs/{load_type.lower()}_completion_rate_runs.png")
plt.close()
# 3. Gráfico: Run-by-Run Waiting Time
plt.figure(figsize=(12, 6))
plt.plot(data[run_col], data['TempoMédioEspera'], marker='o', color=color, linewidth=2, markersize=6)
plt.ylabel('Tempo de Espera (s)')
plt.xlabel('Número da Execução')
plt.title(f'Tempo Médio de Espera por Execução - Carga {load_name}')
plt.grid(alpha=0.3)
plt.savefig(f'graphs/{load_type.lower()}_waiting_time_runs.png', dpi=300, bbox_inches='tight')
print(f"Gráfico guardado: graphs/{load_type.lower()}_waiting_time_runs.png")
plt.close()
# 4. Gráfico: Vehicles Generated vs Completed
plt.figure(figsize=(10, 6))
x = range(len(data))
width = 0.35
plt.bar([i - width/2 for i in x], data['VeículosGerados'], width, label='Gerados', color='lightblue', alpha=0.8)
plt.bar([i + width/2 for i in x], data['VeículosCompletados'], width, label='Concluídos', color=color, alpha=0.8)
plt.ylabel('Número de Veículos')
plt.xlabel('Número da Execução')
plt.title(f'Veículos Gerados vs Concluídos - Carga {load_name}')
plt.xticks(x, data[run_col])
plt.legend()
plt.grid(axis='y', alpha=0.3)
plt.savefig(f'graphs/{load_type.lower()}_vehicles_comparison.png', dpi=300, bbox_inches='tight')
print(f"Gráfico guardado: graphs/{load_type.lower()}_vehicles_comparison.png")
plt.close()
# 5. Gráfico: Summary Statistics (4-panel)
fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(2, 2, figsize=(14, 10))
# Panel 1: Dwelling Time Statistics
metrics = ['Média', 'Mínimo', 'Máximo', 'Desvio\nPadrão']
values = [
data['TempoMédioSistema'].mean(),
data['TempoMínimoSistema'].min(),
data['TempoMáximoSistema'].max(),
data['TempoMédioSistema'].std()
]
ax1.bar(metrics, values, color=[color, 'lightblue', 'darkblue', 'gray'])
ax1.set_title('Estatísticas de Tempo no Sistema')
ax1.set_ylabel('Tempo (s)')
ax1.grid(axis='y', alpha=0.3)
for i, v in enumerate(values):
ax1.text(i, v + 0.5, f'{v:.2f}s', ha='center', va='bottom')
# Panel 2: Waiting Time Statistics
values = [
data['TempoMédioEspera'].mean(),
data['TempoMédioEspera'].min(),
data['TempoMédioEspera'].max(),
data['TempoMédioEspera'].std()
]
ax2.bar(metrics, values, color=[color, 'lightblue', 'darkblue', 'gray'])
ax2.set_title('Estatísticas de Tempo de Espera')
ax2.set_ylabel('Tempo (s)')
ax2.grid(axis='y', alpha=0.3)
for i, v in enumerate(values):
ax2.text(i, v + 0.5, f'{v:.2f}s', ha='center', va='bottom')
# Panel 3: Completion Rate Distribution
ax3.hist(data['TaxaConclusão'], bins=10, color=color, alpha=0.7, edgecolor='black')
ax3.axvline(data['TaxaConclusão'].mean(), color='red', linestyle='--', linewidth=2, label='Média')
ax3.set_title('Distribuição da Taxa de Conclusão')
ax3.set_xlabel('Taxa de Conclusão (%)')
ax3.set_ylabel('Frequência')
ax3.legend()
ax3.grid(axis='y', alpha=0.3)
# Panel 4: Key Metrics Summary
summary_metrics = ['Veículos\nGerados', 'Veículos\nConcluídos', 'Taxa de\nConclusão (%)']
summary_values = [
data['VeículosGerados'].mean(),
data['VeículosCompletados'].mean(),
data['TaxaConclusão'].mean()
]
# Create bars individually with different alpha values
alphas = [0.5, 0.7, 0.9]
for i, (metric, value, alpha_val) in enumerate(zip(summary_metrics, summary_values, alphas)):
ax4.bar(i, value, color=color, alpha=alpha_val)
ax4.set_xticks(range(len(summary_metrics)))
ax4.set_xticklabels(summary_metrics)
ax4.set_title('Resumo de Métricas-Chave')
ax4.grid(axis='y', alpha=0.3)
for i, v in enumerate(summary_values):
ax4.text(i, v + max(summary_values)*0.02, f'{v:.1f}', ha='center', va='bottom', fontweight='bold')
plt.tight_layout()
plt.savefig(f'graphs/{load_type.lower()}_summary_statistics.png', dpi=300, bbox_inches='tight')
print(f"Gráfico guardado: graphs/{load_type.lower()}_summary_statistics.png")
plt.close()
# Print detailed summary statistics
print(f"\n{'='*60}")
print(f"CARGA {load_name.upper()} - ESTATÍSTICAS DETALHADAS")
print("="*60)
print(f"\nTEMPO NO SISTEMA:")
print(f" Média: {data['TempoMédioSistema'].mean():.2f}s")
print(f" Desvio Padrão: {data['TempoMédioSistema'].std():.2f}s")
print(f" Mínimo: {data['TempoMínimoSistema'].min():.2f}s")
print(f" Máximo: {data['TempoMáximoSistema'].max():.2f}s")
print(f" Mediana: {data['TempoMédioSistema'].median():.2f}s")
print(f"\nTEMPO DE ESPERA:")
print(f" Média: {data['TempoMédioEspera'].mean():.2f}s")
print(f" Desvio Padrão: {data['TempoMédioEspera'].std():.2f}s")
print(f" Mínimo: {data['TempoMédioEspera'].min():.2f}s")
print(f" Máximo: {data['TempoMédioEspera'].max():.2f}s")
print(f" Mediana: {data['TempoMédioEspera'].median():.2f}s")
print(f"\nTAXA DE CONCLUSÃO:")
print(f" Média: {data['TaxaConclusão'].mean():.2f}%")
print(f" Desvio Padrão: {data['TaxaConclusão'].std():.2f}%")
print(f" Mínimo: {data['TaxaConclusão'].min():.2f}%")
print(f" Máximo: {data['TaxaConclusão'].max():.2f}%")
print(f" Mediana: {data['TaxaConclusão'].median():.2f}%")
print(f"\nCONTAGEM DE VEÍCULOS:")
print(f" Média Gerados: {data['VeículosGerados'].mean():.0f}")
print(f" Média Concluídos: {data['VeículosCompletados'].mean():.0f}")
print(f" Média Perdidos: {data['VeículosGerados'].mean() - data['VeículosCompletados'].mean():.0f}")
print(f"\nEXECUÇÕES ANALISADAS: {len(data)}")
# Check for config file column - could be ArquivoConfig or ConfigFile
config_col = None
if 'ArquivoConfig' in data.columns:
config_col = 'ArquivoConfig'
elif 'ConfigFile' in data.columns:
config_col = 'ConfigFile'
if config_col:
print(f"FICHEIRO DE CONFIGURAÇÃO: {data[config_col].iloc[0]}")
# Generate individual graphs for each load
generate_individual_graphs(low, 'LOW', 'Baixa', 'green')
generate_individual_graphs(medium, 'MEDIUM', 'Média', 'orange')
generate_individual_graphs(high, 'HIGH', 'Alta', 'red')
# ==============================================================================
# SUMÁRIO FINAL
# ==============================================================================
print("\n" + "="*60)
print("SUMÁRIO COMPARATIVO FINAL")
print("="*60)
print(f"\nCARGA BAIXA:")
print(f" Tempo Médio no Sistema: {low['TempoMédioSistema'].mean():.2f}s")
print(f" Tempo Médio de Espera: {low['TempoMédioEspera'].mean():.2f}s")
print(f" Taxa de Conclusão: {low['TaxaConclusão'].mean():.1f}%")
print(f" Veículos Gerados: {low['VeículosGerados'].mean():.0f}")
print(f" Veículos Concluídos: {low['VeículosCompletados'].mean():.0f}")
print(f"\nCARGA MÉDIA:")
print(f" Tempo Médio no Sistema: {medium['TempoMédioSistema'].mean():.2f}s")
print(f" Tempo Médio de Espera: {medium['TempoMédioEspera'].mean():.2f}s")
print(f" Taxa de Conclusão: {medium['TaxaConclusão'].mean():.1f}%")
print(f" Veículos Gerados: {medium['VeículosGerados'].mean():.0f}")
print(f" Veículos Concluídos: {medium['VeículosCompletados'].mean():.0f}")
print(f"\nCARGA ALTA:")
print(f" Tempo Médio no Sistema: {high['TempoMédioSistema'].mean():.2f}s")
print(f" Tempo Médio de Espera: {high['TempoMédioEspera'].mean():.2f}s")
print(f" Taxa de Conclusão: {high['TaxaConclusão'].mean():.1f}%")
print(f" Veículos Gerados: {high['VeículosGerados'].mean():.0f}")
print(f" Veículos Concluídos: {high['VeículosCompletados'].mean():.0f}")
print("\n" + "="*60)
print("ANÁLISE COMPLETA!")
print(f"Total de gráficos gerados: 19")
print("Todos os gráficos foram guardados no diretório 'graphs/'")
print("="*60)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 111 KiB

After

Width:  |  Height:  |  Size: 116 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 135 KiB

After

Width:  |  Height:  |  Size: 140 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 95 KiB

After

Width:  |  Height:  |  Size: 99 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 168 KiB

After

Width:  |  Height:  |  Size: 173 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 109 KiB

After

Width:  |  Height:  |  Size: 113 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 184 KiB

After

Width:  |  Height:  |  Size: 188 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 95 KiB

After

Width:  |  Height:  |  Size: 100 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 164 KiB

After

Width:  |  Height:  |  Size: 168 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 129 KiB

After

Width:  |  Height:  |  Size: 134 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 159 KiB

After

Width:  |  Height:  |  Size: 163 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 88 KiB

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 138 KiB

After

Width:  |  Height:  |  Size: 142 KiB