histlearn commited on
Commit
cbf8ae9
·
verified ·
1 Parent(s): 6fb5c26

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +96 -38
app.py CHANGED
@@ -241,46 +241,77 @@ class ReportGenerator:
241
  return plt.gcf()
242
 
243
  def create_time_performance_plot(self) -> plt.Figure:
244
- """Cria o gráfico de relação entre tempo e acertos."""
245
  plt.figure(figsize=(15, 10))
246
-
 
 
 
 
247
  # Scatter plot com cores por nível
248
  for nivel, color in self.colors.items():
249
  mask = self.data['Nível'] == nivel
250
  tempo = pd.to_timedelta(self.data[mask]['Total Tempo']).dt.total_seconds() / 60
251
-
252
  plt.scatter(tempo, self.data[mask]['Acertos Absolutos'],
253
  c=color, label=nivel, alpha=0.7, s=150)
254
-
255
- # Adiciona rótulos otimizados
256
- for i, (x, y, nome) in enumerate(zip(tempo,
257
- self.data[mask]['Acertos Absolutos'],
258
- self.data[mask]['Nome do Aluno'])):
259
  if x > np.median(tempo.values):
260
  ha = 'right'
261
- offset = (-5, 0)
262
  else:
263
  ha = 'left'
264
- offset = (5, 0)
265
-
266
- plt.annotate(nome, (x, y),
267
- xytext=offset, textcoords='offset points',
268
- ha=ha, va='center', rotation=30, fontsize=8,
269
- bbox=dict(facecolor='white', edgecolor='none',
270
- alpha=0.7))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
271
 
272
  plt.title('Relação entre Tempo e Acertos por Nível', pad=20)
273
  plt.xlabel('Tempo Total (minutos)')
274
  plt.ylabel('Número de Acertos')
275
- plt.legend(bbox_to_anchor=(1.05, 1), loc='upper left')
276
- plt.grid(True, alpha=0.3)
277
-
 
 
 
 
 
 
 
 
 
278
  return plt.gcf()
279
 
280
  def create_tasks_performance_plot(self) -> plt.Figure:
281
- """Cria o gráfico de relação entre tarefas e acertos."""
282
  plt.figure(figsize=(15, 10))
283
-
 
 
 
 
284
  # Scatter plot com cores por nível
285
  for nivel, color in self.colors.items():
286
  mask = self.data['Nível'] == nivel
@@ -288,20 +319,38 @@ class ReportGenerator:
288
  self.data[mask]['Acertos Absolutos'],
289
  c=color, alpha=0.7, s=150, label=nivel)
290
 
291
- # Adiciona rótulos otimizados
292
- for i, row in self.data.iterrows():
293
- if row['Tarefas Completadas'] > np.median(self.data['Tarefas Completadas']):
294
- ha = 'right'
295
- offset = (-5, 0)
296
- else:
297
- ha = 'left'
298
- offset = (5, 0)
 
 
 
 
299
 
300
- plt.annotate(row['Nome do Aluno'],
301
- (row['Tarefas Completadas'], row['Acertos Absolutos']),
302
- xytext=offset, textcoords='offset points',
303
- ha=ha, va='center', rotation=30, fontsize=8,
304
- bbox=dict(facecolor='white', edgecolor='none', alpha=0.7))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
305
 
306
  # Linha de tendência
307
  z = np.polyfit(self.data['Tarefas Completadas'],
@@ -309,16 +358,25 @@ class ReportGenerator:
309
  p = np.poly1d(z)
310
  x_range = np.linspace(self.data['Tarefas Completadas'].min(),
311
  self.data['Tarefas Completadas'].max(), 100)
312
-
313
  plt.plot(x_range, p(x_range), "--", color='#e74c3c', alpha=0.8,
314
  label='Tendência', linewidth=2)
315
 
316
  plt.title('Relação entre Tarefas Completadas e Acertos', pad=20)
317
  plt.xlabel('Número de Tarefas Completadas')
318
  plt.ylabel('Número de Acertos')
319
- plt.legend(bbox_to_anchor=(1.05, 1), loc='upper left')
320
- plt.grid(True, alpha=0.3)
321
-
 
 
 
 
 
 
 
 
 
322
  return plt.gcf()
323
 
324
  def generate_graphs(self) -> List[plt.Figure]:
 
241
  return plt.gcf()
242
 
243
  def create_time_performance_plot(self) -> plt.Figure:
244
+ """Cria o gráfico de relação entre tempo e acertos com melhor legibilidade."""
245
  plt.figure(figsize=(15, 10))
246
+
247
+ # Configurar fundo e grade
248
+ plt.grid(True, alpha=0.2, linestyle='--')
249
+ plt.gca().set_facecolor('#f8f9fa')
250
+
251
  # Scatter plot com cores por nível
252
  for nivel, color in self.colors.items():
253
  mask = self.data['Nível'] == nivel
254
  tempo = pd.to_timedelta(self.data[mask]['Total Tempo']).dt.total_seconds() / 60
255
+
256
  plt.scatter(tempo, self.data[mask]['Acertos Absolutos'],
257
  c=color, label=nivel, alpha=0.7, s=150)
258
+
259
+ # Melhorar posicionamento dos rótulos
260
+ for x, y, nome in zip(tempo, self.data[mask]['Acertos Absolutos'],
261
+ self.data[mask]['Nome do Aluno']):
262
+ # Calcular a posição do texto para evitar sobreposição
263
  if x > np.median(tempo.values):
264
  ha = 'right'
265
+ offset = (-10, 0)
266
  else:
267
  ha = 'left'
268
+ offset = (10, 0)
269
+
270
+ # Adicionar pequena linha conectora
271
+ plt.annotate(nome,
272
+ xy=(x, y),
273
+ xytext=(x + offset[0]/5, y + 0.3),
274
+ ha=ha,
275
+ va='bottom',
276
+ fontsize=8,
277
+ bbox=dict(
278
+ facecolor='white',
279
+ edgecolor='none',
280
+ alpha=0.8,
281
+ pad=0.5
282
+ ),
283
+ arrowprops=dict(
284
+ arrowstyle='-',
285
+ color='gray',
286
+ alpha=0.3,
287
+ connectionstyle='arc3,rad=0'
288
+ ))
289
 
290
  plt.title('Relação entre Tempo e Acertos por Nível', pad=20)
291
  plt.xlabel('Tempo Total (minutos)')
292
  plt.ylabel('Número de Acertos')
293
+
294
+ # Melhorar posição e aparência da legenda
295
+ plt.legend(bbox_to_anchor=(1.05, 1),
296
+ loc='upper left',
297
+ borderaxespad=0,
298
+ frameon=True,
299
+ facecolor='white',
300
+ edgecolor='none')
301
+
302
+ # Ajustar margens para acomodar a legenda
303
+ plt.tight_layout()
304
+
305
  return plt.gcf()
306
 
307
  def create_tasks_performance_plot(self) -> plt.Figure:
308
+ """Cria o gráfico de relação entre tarefas e acertos com melhor legibilidade."""
309
  plt.figure(figsize=(15, 10))
310
+
311
+ # Configurar fundo e grade
312
+ plt.grid(True, alpha=0.2, linestyle='--')
313
+ plt.gca().set_facecolor('#f8f9fa')
314
+
315
  # Scatter plot com cores por nível
316
  for nivel, color in self.colors.items():
317
  mask = self.data['Nível'] == nivel
 
319
  self.data[mask]['Acertos Absolutos'],
320
  c=color, alpha=0.7, s=150, label=nivel)
321
 
322
+ # Melhorar posicionamento dos rótulos
323
+ for _, row in self.data[mask].iterrows():
324
+ x = row['Tarefas Completadas']
325
+ y = row['Acertos Absolutos']
326
+
327
+ # Calcular posição do texto para evitar sobreposição
328
+ if x > np.median(self.data['Tarefas Completadas']):
329
+ ha = 'right'
330
+ offset = (-10, 0)
331
+ else:
332
+ ha = 'left'
333
+ offset = (10, 0)
334
 
335
+ # Adicionar pequena linha conectora
336
+ plt.annotate(row['Nome do Aluno'],
337
+ xy=(x, y),
338
+ xytext=(x + offset[0]/5, y + 0.3),
339
+ ha=ha,
340
+ va='bottom',
341
+ fontsize=8,
342
+ bbox=dict(
343
+ facecolor='white',
344
+ edgecolor='none',
345
+ alpha=0.8,
346
+ pad=0.5
347
+ ),
348
+ arrowprops=dict(
349
+ arrowstyle='-',
350
+ color='gray',
351
+ alpha=0.3,
352
+ connectionstyle='arc3,rad=0'
353
+ ))
354
 
355
  # Linha de tendência
356
  z = np.polyfit(self.data['Tarefas Completadas'],
 
358
  p = np.poly1d(z)
359
  x_range = np.linspace(self.data['Tarefas Completadas'].min(),
360
  self.data['Tarefas Completadas'].max(), 100)
361
+
362
  plt.plot(x_range, p(x_range), "--", color='#e74c3c', alpha=0.8,
363
  label='Tendência', linewidth=2)
364
 
365
  plt.title('Relação entre Tarefas Completadas e Acertos', pad=20)
366
  plt.xlabel('Número de Tarefas Completadas')
367
  plt.ylabel('Número de Acertos')
368
+
369
+ # Melhorar posição e aparência da legenda
370
+ plt.legend(bbox_to_anchor=(1.05, 1),
371
+ loc='upper left',
372
+ borderaxespad=0,
373
+ frameon=True,
374
+ facecolor='white',
375
+ edgecolor='none')
376
+
377
+ # Ajustar margens para acomodar a legenda
378
+ plt.tight_layout()
379
+
380
  return plt.gcf()
381
 
382
  def generate_graphs(self) -> List[plt.Figure]: