Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -368,17 +368,17 @@ class ReportGenerator:
|
|
368 |
return plt.gcf()
|
369 |
|
370 |
def create_tasks_performance_plot(self) -> plt.Figure:
|
371 |
-
"""Cria o gráfico de relação entre tarefas e acertos com
|
372 |
plt.figure(figsize=(15, 10))
|
373 |
|
374 |
# Configurar fundo e grade
|
375 |
plt.grid(True, alpha=0.2, linestyle='--')
|
376 |
plt.gca().set_facecolor('#f8f9fa')
|
377 |
|
378 |
-
#
|
379 |
-
|
380 |
|
381 |
-
# Primeiro, plotar os pontos
|
382 |
for nivel, color in self.colors.items():
|
383 |
mask = self.data['Nível'] == nivel
|
384 |
tarefas = self.data[mask]['Tarefas Completadas']
|
@@ -386,14 +386,14 @@ class ReportGenerator:
|
|
386 |
|
387 |
plt.scatter(tarefas, acertos, c=color, label=nivel, alpha=0.7, s=150)
|
388 |
|
389 |
-
# Agrupar
|
390 |
-
for
|
391 |
-
key = (
|
392 |
-
if key not in
|
393 |
-
|
394 |
-
|
395 |
|
396 |
-
#
|
397 |
z = np.polyfit(self.data['Tarefas Completadas'],
|
398 |
self.data['Acertos Absolutos'], 1)
|
399 |
p = np.poly1d(z)
|
@@ -405,73 +405,74 @@ class ReportGenerator:
|
|
405 |
plt.plot(x_range, p(x_range), "--", color='#e74c3c', alpha=0.8,
|
406 |
label='Tendência', linewidth=2)
|
407 |
|
408 |
-
# Adicionar anotações
|
409 |
-
for
|
410 |
-
if len(
|
411 |
-
#
|
412 |
-
x, y, nome = group[0]
|
413 |
plt.annotate(
|
414 |
-
|
415 |
-
(
|
416 |
xytext=(5, 5),
|
417 |
textcoords='offset points',
|
418 |
bbox=dict(
|
419 |
facecolor='white',
|
420 |
edgecolor='none',
|
421 |
-
alpha=0.
|
422 |
-
pad=0.5
|
|
|
423 |
),
|
424 |
-
fontsize=8
|
425 |
-
arrowprops=dict(
|
426 |
-
arrowstyle='-',
|
427 |
-
color='gray',
|
428 |
-
alpha=0.3,
|
429 |
-
connectionstyle='arc3,rad=0.3'
|
430 |
-
)
|
431 |
)
|
432 |
else:
|
433 |
-
# Múltiplos
|
434 |
-
|
435 |
-
|
436 |
-
|
437 |
|
438 |
-
#
|
439 |
-
|
440 |
-
y_text = y_base + (0.5 if y_base < np.mean(self.data['Acertos Absolutos']) else -2)
|
441 |
-
|
442 |
-
# Criar caixa com lista de nomes
|
443 |
nome_text = '\n'.join(nomes)
|
|
|
|
|
444 |
plt.annotate(
|
445 |
nome_text,
|
446 |
-
(
|
447 |
-
xytext=(
|
|
|
448 |
bbox=dict(
|
449 |
facecolor='white',
|
450 |
edgecolor='lightgray',
|
451 |
-
alpha=0.
|
452 |
pad=0.5,
|
453 |
boxstyle='round,pad=0.5'
|
454 |
),
|
455 |
fontsize=8,
|
456 |
arrowprops=dict(
|
457 |
-
arrowstyle='
|
|
|
458 |
color='gray',
|
459 |
-
alpha=0.
|
460 |
-
|
461 |
-
|
462 |
)
|
463 |
|
464 |
-
|
465 |
-
plt.
|
466 |
-
plt.
|
|
|
467 |
|
|
|
|
|
|
|
|
|
468 |
plt.legend(
|
469 |
bbox_to_anchor=(1.05, 1),
|
470 |
loc='upper left',
|
471 |
borderaxespad=0,
|
472 |
frameon=True,
|
473 |
facecolor='white',
|
474 |
-
edgecolor='none'
|
|
|
475 |
)
|
476 |
|
477 |
plt.tight_layout()
|
|
|
368 |
return plt.gcf()
|
369 |
|
370 |
def create_tasks_performance_plot(self) -> plt.Figure:
|
371 |
+
"""Cria o gráfico de relação entre tarefas e acertos com visualização aprimorada."""
|
372 |
plt.figure(figsize=(15, 10))
|
373 |
|
374 |
# Configurar fundo e grade
|
375 |
plt.grid(True, alpha=0.2, linestyle='--')
|
376 |
plt.gca().set_facecolor('#f8f9fa')
|
377 |
|
378 |
+
# Criar dicionário para agrupar alunos por tarefa/acerto
|
379 |
+
task_groups = {}
|
380 |
|
381 |
+
# Primeiro, plotar os pontos
|
382 |
for nivel, color in self.colors.items():
|
383 |
mask = self.data['Nível'] == nivel
|
384 |
tarefas = self.data[mask]['Tarefas Completadas']
|
|
|
386 |
|
387 |
plt.scatter(tarefas, acertos, c=color, label=nivel, alpha=0.7, s=150)
|
388 |
|
389 |
+
# Agrupar alunos com mesmas tarefas/acertos
|
390 |
+
for t, a, nome in zip(tarefas, acertos, self.data[mask]['Nome do Aluno']):
|
391 |
+
key = (t, a)
|
392 |
+
if key not in task_groups:
|
393 |
+
task_groups[key] = []
|
394 |
+
task_groups[key].append(nome.split()[0]) # Usar apenas primeiro nome
|
395 |
|
396 |
+
# Linha de tendência
|
397 |
z = np.polyfit(self.data['Tarefas Completadas'],
|
398 |
self.data['Acertos Absolutos'], 1)
|
399 |
p = np.poly1d(z)
|
|
|
405 |
plt.plot(x_range, p(x_range), "--", color='#e74c3c', alpha=0.8,
|
406 |
label='Tendência', linewidth=2)
|
407 |
|
408 |
+
# Adicionar anotações agrupadas
|
409 |
+
for (tarefas, acertos), nomes in task_groups.items():
|
410 |
+
if len(nomes) == 1:
|
411 |
+
# Caso único - anotação simples
|
|
|
412 |
plt.annotate(
|
413 |
+
nomes[0],
|
414 |
+
(tarefas, acertos),
|
415 |
xytext=(5, 5),
|
416 |
textcoords='offset points',
|
417 |
bbox=dict(
|
418 |
facecolor='white',
|
419 |
edgecolor='none',
|
420 |
+
alpha=0.9,
|
421 |
+
pad=0.5,
|
422 |
+
boxstyle='round'
|
423 |
),
|
424 |
+
fontsize=8
|
|
|
|
|
|
|
|
|
|
|
|
|
425 |
)
|
426 |
else:
|
427 |
+
# Múltiplos alunos - criar caixa agrupada
|
428 |
+
# Calcular posição baseada no quadrante
|
429 |
+
x_dir = 1 if tarefas < np.mean(self.data['Tarefas Completadas']) else -1
|
430 |
+
y_dir = 1 if acertos < np.mean(self.data['Acertos Absolutos']) else -1
|
431 |
|
432 |
+
# Criar texto com nomes em ordem alfabética
|
433 |
+
nomes.sort()
|
|
|
|
|
|
|
434 |
nome_text = '\n'.join(nomes)
|
435 |
+
|
436 |
+
# Adicionar conectores curvos e caixa de texto
|
437 |
plt.annotate(
|
438 |
nome_text,
|
439 |
+
(tarefas, acertos),
|
440 |
+
xytext=(x_dir * 30, y_dir * 30),
|
441 |
+
textcoords='offset points',
|
442 |
bbox=dict(
|
443 |
facecolor='white',
|
444 |
edgecolor='lightgray',
|
445 |
+
alpha=0.95,
|
446 |
pad=0.5,
|
447 |
boxstyle='round,pad=0.5'
|
448 |
),
|
449 |
fontsize=8,
|
450 |
arrowprops=dict(
|
451 |
+
arrowstyle='fancy',
|
452 |
+
connectionstyle=f'arc3,rad={0.2 * x_dir}',
|
453 |
color='gray',
|
454 |
+
alpha=0.6
|
455 |
+
),
|
456 |
+
ha='center'
|
457 |
)
|
458 |
|
459 |
+
# Configurações finais
|
460 |
+
plt.title('Relação entre Tarefas Completadas e Acertos', pad=20, fontsize=14)
|
461 |
+
plt.xlabel('Número de Tarefas Completadas', fontsize=12)
|
462 |
+
plt.ylabel('Número de Acertos', fontsize=12)
|
463 |
|
464 |
+
# Ajustar limites para acomodar as anotações
|
465 |
+
plt.margins(x=0.15, y=0.15)
|
466 |
+
|
467 |
+
# Legenda melhorada
|
468 |
plt.legend(
|
469 |
bbox_to_anchor=(1.05, 1),
|
470 |
loc='upper left',
|
471 |
borderaxespad=0,
|
472 |
frameon=True,
|
473 |
facecolor='white',
|
474 |
+
edgecolor='none',
|
475 |
+
fontsize=10
|
476 |
)
|
477 |
|
478 |
plt.tight_layout()
|