histlearn commited on
Commit
2c2830b
·
verified ·
1 Parent(s): 1586794

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +26 -80
app.py CHANGED
@@ -433,7 +433,7 @@ def plotar_graficos_destacados(disciplinas_dados: List[Dict], temp_dir: str) ->
433
  raise ValueError("Nenhuma disciplina válida encontrada no boletim.")
434
 
435
  # Configuração do estilo
436
- plt.style.use('seaborn')
437
  fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(12, 10),
438
  height_ratios=[1, 1])
439
  plt.subplots_adjust(hspace=0.4)
@@ -459,129 +459,75 @@ def plotar_graficos_destacados(disciplinas_dados: List[Dict], temp_dir: str) ->
459
  ax.spines['top'].set_visible(False)
460
  ax.spines['right'].set_visible(False)
461
 
 
 
 
 
462
  # Gráfico de notas
463
  barras_notas = ax1.bar(disciplinas, medias_notas, color=cores_notas)
464
  ax1.set_title('Média de Notas por Disciplina',
465
  pad=20, fontsize=14, fontweight='bold')
466
  ax1.set_ylim(0, ESCALA_MAXIMA_NOTAS)
467
- ax1.set_xticklabels(disciplinas, rotation=45,
468
- ha='right', va='top', fontsize=10)
469
  ax1.set_ylabel('Notas', fontsize=12, labelpad=10)
470
 
471
  # Linha de média mínima
472
- ax1.axhline(y=LIMITE_APROVACAO_NOTA,
473
- color=COR_REPROVADO,
474
- linestyle='--',
475
- alpha=0.3,
476
- linewidth=2)
477
- ax1.text(0.02, LIMITE_APROVACAO_NOTA + 0.1,
478
- 'Média mínima (5,0)',
479
- transform=ax1.get_yaxis_transform(),
480
- color=COR_REPROVADO,
481
- alpha=0.7,
482
- fontsize=10)
483
 
484
  # Valores nas barras de notas
485
  for barra in barras_notas:
486
  altura = barra.get_height()
487
  cor_texto = 'white' if altura >= LIMITE_APROVACAO_NOTA else 'black'
488
  ax1.text(barra.get_x() + barra.get_width()/2., altura,
489
- f'{altura:.1f}',
490
- ha='center',
491
- va='bottom',
492
- fontsize=10,
493
- bbox=dict(
494
- facecolor='white',
495
- edgecolor='none',
496
- alpha=0.7,
497
- pad=1
498
- ),
499
- color=cor_texto if altura >= 8 else 'black')
500
 
501
  # Gráfico de frequências
502
  barras_freq = ax2.bar(disciplinas, medias_freq, color=cores_freq)
503
- ax2.set_title('Frequência Média por Disciplina',
504
- pad=20, fontsize=14, fontweight='bold')
505
  ax2.set_ylim(0, 110)
506
- ax2.set_xticklabels(disciplinas, rotation=45,
507
- ha='right', va='top', fontsize=10)
508
  ax2.set_ylabel('Frequência (%)', fontsize=12, labelpad=10)
509
 
510
  # Linha de frequência mínima
511
- ax2.axhline(y=LIMITE_APROVACAO_FREQ,
512
- color=COR_REPROVADO,
513
- linestyle='--',
514
- alpha=0.3,
515
- linewidth=2)
516
- ax2.text(0.02, LIMITE_APROVACAO_FREQ + 1,
517
- 'Frequência mínima (75%)',
518
- transform=ax2.get_yaxis_transform(),
519
- color=COR_REPROVADO,
520
- alpha=0.7,
521
- fontsize=10)
522
 
523
  # Valores nas barras de frequência
524
  for barra in barras_freq:
525
  altura = barra.get_height()
526
  cor_texto = 'white' if altura >= LIMITE_APROVACAO_FREQ else 'black'
527
  ax2.text(barra.get_x() + barra.get_width()/2., altura,
528
- f'{altura:.1f}%',
529
- ha='center',
530
- va='bottom',
531
- fontsize=10,
532
- bbox=dict(
533
- facecolor='white',
534
- edgecolor='none',
535
- alpha=0.7,
536
- pad=1
537
- ),
538
- color=cor_texto if altura >= 90 else 'black')
539
 
540
  # Título global com estilo
541
  plt.suptitle(
542
  f'Desempenho Geral\nMédia Global: {media_global:.1f} | Frequência Global: {freq_global:.1f}%',
543
- y=0.98,
544
- fontsize=16,
545
- fontweight='bold',
546
- bbox=dict(
547
- facecolor='white',
548
- edgecolor='none',
549
- alpha=0.8,
550
- pad=5,
551
- boxstyle='round,pad=0.5'
552
- )
553
  )
554
 
555
  # Aviso de reprovação estilizado
556
  if freq_global < LIMITE_APROVACAO_FREQ:
557
- plt.figtext(0.5, 0.02,
558
- "Atenção: Risco de Reprovação por Baixa Frequência",
559
- ha="center",
560
- fontsize=12,
561
- color=COR_REPROVADO,
562
- weight='bold',
563
- bbox=dict(
564
- facecolor='#FFEBEE',
565
- edgecolor=COR_REPROVADO,
566
- alpha=0.9,
567
- pad=5,
568
- boxstyle='round,pad=0.5'
569
- ))
570
 
571
  plt.tight_layout()
572
 
573
  # Salvar com alta qualidade
574
  plot_path = os.path.join(temp_dir, 'medias_frequencias.png')
575
- plt.savefig(plot_path,
576
- bbox_inches='tight',
577
- dpi=300,
578
- facecolor='white',
579
- edgecolor='none')
580
  plt.close()
581
 
582
  return plot_path
583
 
584
-
585
  # Funções de processamento do PDF e geração de relatórios
586
  def gerar_relatorio_pdf(df: pd.DataFrame, disciplinas_dados: List[Dict],
587
  grafico_basica: str, grafico_diversificada: str,
 
433
  raise ValueError("Nenhuma disciplina válida encontrada no boletim.")
434
 
435
  # Configuração do estilo
436
+ plt.style.use('seaborn-v0_8-darkgrid')
437
  fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(12, 10),
438
  height_ratios=[1, 1])
439
  plt.subplots_adjust(hspace=0.4)
 
459
  ax.spines['top'].set_visible(False)
460
  ax.spines['right'].set_visible(False)
461
 
462
+ # Definir os ticks do eixo x para corresponder ao número de disciplinas
463
+ ax1.set_xticks(range(n_disciplinas))
464
+ ax2.set_xticks(range(n_disciplinas))
465
+
466
  # Gráfico de notas
467
  barras_notas = ax1.bar(disciplinas, medias_notas, color=cores_notas)
468
  ax1.set_title('Média de Notas por Disciplina',
469
  pad=20, fontsize=14, fontweight='bold')
470
  ax1.set_ylim(0, ESCALA_MAXIMA_NOTAS)
471
+ ax1.set_xticklabels(disciplinas, rotation=45, ha='right', va='top', fontsize=10)
 
472
  ax1.set_ylabel('Notas', fontsize=12, labelpad=10)
473
 
474
  # Linha de média mínima
475
+ ax1.axhline(y=LIMITE_APROVACAO_NOTA, color=COR_REPROVADO, linestyle='--', alpha=0.3, linewidth=2)
476
+ ax1.text(0.02, LIMITE_APROVACAO_NOTA + 0.1, 'Média mínima (5,0)',
477
+ transform=ax1.get_yaxis_transform(), color=COR_REPROVADO, alpha=0.7, fontsize=10)
 
 
 
 
 
 
 
 
478
 
479
  # Valores nas barras de notas
480
  for barra in barras_notas:
481
  altura = barra.get_height()
482
  cor_texto = 'white' if altura >= LIMITE_APROVACAO_NOTA else 'black'
483
  ax1.text(barra.get_x() + barra.get_width()/2., altura,
484
+ f'{altura:.1f}', ha='center', va='bottom', fontsize=10,
485
+ bbox=dict(facecolor='white', edgecolor='none', alpha=0.7, pad=1),
486
+ color=cor_texto if altura >= 8 else 'black')
 
 
 
 
 
 
 
 
487
 
488
  # Gráfico de frequências
489
  barras_freq = ax2.bar(disciplinas, medias_freq, color=cores_freq)
490
+ ax2.set_title('Frequência Média por Disciplina', pad=20, fontsize=14, fontweight='bold')
 
491
  ax2.set_ylim(0, 110)
492
+ ax2.set_xticklabels(disciplinas, rotation=45, ha='right', va='top', fontsize=10)
 
493
  ax2.set_ylabel('Frequência (%)', fontsize=12, labelpad=10)
494
 
495
  # Linha de frequência mínima
496
+ ax2.axhline(y=LIMITE_APROVACAO_FREQ, color=COR_REPROVADO, linestyle='--', alpha=0.3, linewidth=2)
497
+ ax2.text(0.02, LIMITE_APROVACAO_FREQ + 1, 'Frequência mínima (75%)',
498
+ transform=ax2.get_yaxis_transform(), color=COR_REPROVADO, alpha=0.7, fontsize=10)
 
 
 
 
 
 
 
 
499
 
500
  # Valores nas barras de frequência
501
  for barra in barras_freq:
502
  altura = barra.get_height()
503
  cor_texto = 'white' if altura >= LIMITE_APROVACAO_FREQ else 'black'
504
  ax2.text(barra.get_x() + barra.get_width()/2., altura,
505
+ f'{altura:.1f}%', ha='center', va='bottom', fontsize=10,
506
+ bbox=dict(facecolor='white', edgecolor='none', alpha=0.7, pad=1),
507
+ color=cor_texto if altura >= 90 else 'black')
 
 
 
 
 
 
 
 
508
 
509
  # Título global com estilo
510
  plt.suptitle(
511
  f'Desempenho Geral\nMédia Global: {media_global:.1f} | Frequência Global: {freq_global:.1f}%',
512
+ y=0.98, fontsize=16, fontweight='bold',
513
+ bbox=dict(facecolor='white', edgecolor='none', alpha=0.8, pad=5, boxstyle='round,pad=0.5')
 
 
 
 
 
 
 
 
514
  )
515
 
516
  # Aviso de reprovação estilizado
517
  if freq_global < LIMITE_APROVACAO_FREQ:
518
+ plt.figtext(0.5, 0.02, "Atenção: Risco de Reprovação por Baixa Frequência",
519
+ ha="center", fontsize=12, color=COR_REPROVADO, weight='bold',
520
+ bbox=dict(facecolor='#FFEBEE', edgecolor=COR_REPROVADO, alpha=0.9, pad=5, boxstyle='round,pad=0.5'))
 
 
 
 
 
 
 
 
 
 
521
 
522
  plt.tight_layout()
523
 
524
  # Salvar com alta qualidade
525
  plot_path = os.path.join(temp_dir, 'medias_frequencias.png')
526
+ plt.savefig(plot_path, bbox_inches='tight', dpi=300, facecolor='white', edgecolor='none')
 
 
 
 
527
  plt.close()
528
 
529
  return plot_path
530
 
 
531
  # Funções de processamento do PDF e geração de relatórios
532
  def gerar_relatorio_pdf(df: pd.DataFrame, disciplinas_dados: List[Dict],
533
  grafico_basica: str, grafico_diversificada: str,