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,74 +405,73 @@ 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 |
plt.annotate(
|
413 |
-
|
414 |
-
(
|
415 |
xytext=(5, 5),
|
416 |
textcoords='offset points',
|
417 |
bbox=dict(
|
418 |
facecolor='white',
|
419 |
edgecolor='none',
|
420 |
-
alpha=0.
|
421 |
-
pad=0.5
|
422 |
-
boxstyle='round'
|
423 |
),
|
424 |
-
fontsize=8
|
|
|
|
|
|
|
|
|
|
|
|
|
425 |
)
|
426 |
else:
|
427 |
-
# Múltiplos
|
428 |
-
|
429 |
-
|
430 |
-
|
431 |
|
432 |
-
#
|
433 |
-
|
434 |
-
|
435 |
|
436 |
-
#
|
|
|
437 |
plt.annotate(
|
438 |
nome_text,
|
439 |
-
(
|
440 |
-
xytext=(
|
441 |
-
textcoords='offset points',
|
442 |
bbox=dict(
|
443 |
facecolor='white',
|
444 |
edgecolor='lightgray',
|
445 |
-
alpha=0.
|
446 |
pad=0.5,
|
447 |
boxstyle='round,pad=0.5'
|
448 |
),
|
449 |
fontsize=8,
|
450 |
arrowprops=dict(
|
451 |
-
arrowstyle='
|
452 |
-
connectionstyle=f'arc3,rad={0.2 * x_dir}',
|
453 |
color='gray',
|
454 |
-
alpha=0.
|
455 |
-
|
456 |
-
|
457 |
)
|
458 |
|
459 |
-
|
460 |
-
plt.
|
461 |
-
plt.
|
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()
|
|
|
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 melhor legibilidade."""
|
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 |
+
# Dicionário para armazenar pontos próximos
|
379 |
+
proximity_groups = {}
|
380 |
|
381 |
+
# Primeiro, plotar os pontos e a linha de tendência
|
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 pontos próximos
|
390 |
+
for x, y, nome in zip(tarefas, acertos, self.data[mask]['Nome do Aluno']):
|
391 |
+
key = (x, y) # Usar valores exatos pois tarefas são discretas
|
392 |
+
if key not in proximity_groups:
|
393 |
+
proximity_groups[key] = []
|
394 |
+
proximity_groups[key].append((x, y, nome))
|
395 |
|
396 |
+
# Adicionar 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 com tratamento especial para pontos próximos
|
409 |
+
for group in proximity_groups.values():
|
410 |
+
if len(group) == 1:
|
411 |
+
# Ponto único - anotação normal
|
412 |
+
x, y, nome = group[0]
|
413 |
plt.annotate(
|
414 |
+
nome.split()[0], # Usar apenas primeiro nome
|
415 |
+
(x, y),
|
416 |
xytext=(5, 5),
|
417 |
textcoords='offset points',
|
418 |
bbox=dict(
|
419 |
facecolor='white',
|
420 |
edgecolor='none',
|
421 |
+
alpha=0.8,
|
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 pontos próximos - criar caixa com lista
|
434 |
+
x_base = sum(p[0] for p in group) / len(group)
|
435 |
+
y_base = sum(p[1] for p in group) / len(group)
|
436 |
+
nomes = [p[2].split()[0] for p in group]
|
437 |
|
438 |
+
# Determinar posição do texto baseado no quadrante do gráfico
|
439 |
+
x_text = x_base + (0.5 if x_base < np.mean(self.data['Tarefas Completadas']) else -2)
|
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 |
+
(x_base, y_base),
|
447 |
+
xytext=(x_text, y_text),
|
|
|
448 |
bbox=dict(
|
449 |
facecolor='white',
|
450 |
edgecolor='lightgray',
|
451 |
+
alpha=0.9,
|
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.5,
|
460 |
+
connectionstyle='arc3,rad=0.2'
|
461 |
+
)
|
462 |
)
|
463 |
|
464 |
+
plt.title('Relação entre Tarefas Completadas e Acertos', pad=20)
|
465 |
+
plt.xlabel('Número de Tarefas Completadas')
|
466 |
+
plt.ylabel('Número de Acertos')
|
|
|
|
|
|
|
|
|
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()
|