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()
|