TKM03 commited on
Commit
bad7662
·
verified ·
1 Parent(s): 06921f8

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +125 -120
app.py CHANGED
@@ -19,7 +19,7 @@ def wait_for_element(driver, locator):
19
  return WebDriverWait(driver, 10).until(EC.element_to_be_clickable(locator))
20
 
21
  def select_date_month_day(driver, date_str, date_input_id):
22
- date_to_select = datetime.strptime(date_str, '%Y#-%m-%d')
23
  date_input = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.ID, date_input_id)))
24
  date_input.click()
25
  month_select = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.CLASS_NAME, 'ui-datepicker-month')))
@@ -287,7 +287,7 @@ def scrape_data(url, user_id, password):
287
 
288
 
289
  # --- Plotting Functions ---
290
- def generate_dashboard_charts(patient_data_by_year, claim_data_by_year, mc_data_by_year, year, show_mc_pct=True):
291
  if not patient_data_by_year or not claim_data_by_year or not mc_data_by_year:
292
  return None, None
293
 
@@ -300,12 +300,13 @@ def generate_dashboard_charts(patient_data_by_year, claim_data_by_year, mc_data_
300
  return None, None
301
 
302
  # Professional styling
303
- sns.set(style="whitegrid", palette="deep")
304
  plt.rcParams.update({
305
- 'font.family': 'Arial', 'font.size': 12, 'axes.titlesize': 14,
306
- 'axes.labelsize': 12, 'xtick.labelsize': 10, 'ytick.labelsize': 10,
307
- 'axes.titleweight': 'bold', 'axes.linewidth': 1.2, 'grid.linestyle': '--',
308
- 'grid.alpha': 0.7, 'figure.facecolor': '#f9f9f9', 'axes.facecolor': '#ffffff'
 
309
  })
310
 
311
  provider_charts = []
@@ -315,12 +316,12 @@ def generate_dashboard_charts(patient_data_by_year, claim_data_by_year, mc_data_
315
  # 1. Total Visits by Providers (Horizontal Bar)
316
  plt.figure(figsize=(12, 6))
317
  top_prov_visits = mc_df.sort_values('No. of Visit', ascending=False).head(10)
318
- sns.barplot(data=top_prov_visits, x='No. of Visit', y='Provider', hue='Provider', palette='Blues_d', legend=False)
319
- plt.title(f'Top 10 Providers by Total Visits ({year})')
320
- plt.xlabel('Total Visits')
321
- plt.ylabel('Provider')
322
  for i, v in enumerate(top_prov_visits['No. of Visit']):
323
- plt.text(v + 0.5, i, f'{int(v)}', va='center', fontsize=10, color='black')
324
  plt.tight_layout()
325
  provider_charts.append(plt.gcf())
326
  plt.close()
@@ -328,30 +329,32 @@ def generate_dashboard_charts(patient_data_by_year, claim_data_by_year, mc_data_
328
  # 2. Total MC by Providers (Horizontal Bar)
329
  plt.figure(figsize=(12, 6))
330
  top_prov_mc = mc_df.sort_values('Total MC Given', ascending=False).head(10)
331
- sns.barplot(data=top_prov_mc, x='Total MC Given', y='Provider', hue='Provider', palette='Greens_d', legend=False)
332
- plt.title(f'Top 10 Providers by Total MC Given ({year})')
333
- plt.xlabel('Total MC (Days)')
334
- plt.ylabel('Provider')
335
  for i, v in enumerate(top_prov_mc['Total MC Given']):
336
- plt.text(v + 0.5, i, f'{int(v)}', va='center', fontsize=10, color='black')
337
  plt.tight_layout()
338
  provider_charts.append(plt.gcf())
339
  plt.close()
340
 
341
- # 3. % MC Given by Providers (Bar) - Based on Top 10 by Visits and MC
342
  if show_mc_pct:
343
- plt.figure(figsize=(12, 6))
344
  top_visits_provs = set(mc_df.sort_values('No. of Visit', ascending=False).head(10)['Provider'])
345
  top_mc_provs = set(mc_df.sort_values('Total MC Given', ascending=False).head(10)['Provider'])
346
  top_provs = top_visits_provs.union(top_mc_provs)
347
- top_prov_mc_pct = mc_df[mc_df['Provider'].isin(top_provs)].sort_values('% MC Given', ascending=False)
348
- sns.barplot(data=top_prov_mc_pct, x='Provider', y='% MC Given', hue='Provider', palette='Purples_d', legend=False)
349
- plt.title(f'% MC Given for Top Providers ({year})')
350
- plt.ylabel('% MC Given')
351
- plt.xlabel('Provider')
352
- plt.xticks(rotation=45, ha='right')
 
 
353
  for i, v in enumerate(top_prov_mc_pct['% MC Given']):
354
- plt.text(i, v + 1, f'{v:.1f}%', ha='center', fontsize=10, color='black')
355
  plt.tight_layout()
356
  provider_charts.append(plt.gcf())
357
  else:
@@ -361,12 +364,13 @@ def generate_dashboard_charts(patient_data_by_year, claim_data_by_year, mc_data_
361
  # 4. Total Claim by Providers (Horizontal Bar)
362
  plt.figure(figsize=(12, 6))
363
  top_prov_claim = claim_df.sort_values('Total Claim', ascending=False).head(10)
364
- sns.barplot(data=top_prov_claim, x='Total Claim', y='Provider Name', hue='Provider Name', palette='Oranges_d', legend=False)
365
- plt.title(f'Top 10 Providers by Total Claim ({year})')
366
- plt.xlabel('Total Claim ($)')
367
- plt.ylabel('Provider')
 
368
  for i, v in enumerate(top_prov_claim['Total Claim']):
369
- plt.text(v + 0.5, i, f'{v:,.2f}', va='center', fontsize=10, color='black')
370
  plt.tight_layout()
371
  provider_charts.append(plt.gcf())
372
  plt.close()
@@ -374,37 +378,29 @@ def generate_dashboard_charts(patient_data_by_year, claim_data_by_year, mc_data_
374
  # 5. Average Claim per Visit by Providers (Bar)
375
  plt.figure(figsize=(12, 6))
376
  top_prov_avg_claim = claim_df.sort_values('Avg Claim per Visit', ascending=False).head(10)
377
- sns.barplot(data=top_prov_avg_claim, x='Provider Name', y='Avg Claim per Visit', hue='Provider Name', palette='Reds_d', legend=False)
378
- plt.title(f'Top 10 Providers by Avg Claim per Visit ({year})')
379
- plt.ylabel('Avg Claim per Visit ($)')
380
- plt.xlabel('Provider')
 
381
  plt.xticks(rotation=45, ha='right')
382
  for i, v in enumerate(top_prov_avg_claim['Avg Claim per Visit']):
383
- plt.text(i, v + 0.5, f'{v:.2f}', ha='center', fontsize=10, color='black')
384
- plt.tight_layout()
385
- provider_charts.append(plt.gcf())
386
- plt.close()
387
-
388
- # 6. Insight: MC vs Claim Correlation (Scatter)
389
- plt.figure(figsize=(12, 6))
390
- sns.scatterplot(data=claim_df, x='Total MC (Days)', y='Total Claim', size='No of Visits', hue='Provider Name', palette='viridis', legend=False)
391
- plt.title(f'MC vs Claim Correlation by Provider ({year})')
392
- plt.xlabel('Total MC (Days)')
393
- plt.ylabel('Total Claim ($)')
394
  plt.tight_layout()
395
  provider_charts.append(plt.gcf())
396
  plt.close()
397
 
398
- # --- Employee Dashboard Charts (unchanged styling for brevity, apply similar updates as above if desired) ---
399
  # 1. Total Visits by Employees
400
  plt.figure(figsize=(12, 6))
401
  top_emp_visits = patient_df.sort_values('Total Visit', ascending=False).head(10)
402
- sns.barplot(data=top_emp_visits, x='Total Visit', y='Employee Name', hue='Employee Name', palette='Blues_d', legend=False)
403
- plt.title(f'Top 10 Employees by Total Visits ({year})')
404
- plt.xlabel('Total Visits')
405
- plt.ylabel('Employee')
 
406
  for i, v in enumerate(top_emp_visits['Total Visit']):
407
- plt.text(v + 0.2, i, f'{int(v)}', va='center', fontsize=10, color='black')
408
  plt.tight_layout()
409
  employee_charts.append(plt.gcf())
410
  plt.close()
@@ -412,12 +408,13 @@ def generate_dashboard_charts(patient_data_by_year, claim_data_by_year, mc_data_
412
  # 2. Total Claim by Employees
413
  plt.figure(figsize=(12, 6))
414
  top_emp_claim = patient_df.sort_values('Total Claim (Combined)', ascending=False).head(10)
415
- sns.barplot(data=top_emp_claim, x='Total Claim (Combined)', y='Employee Name', hue='Employee Name', palette='Oranges_d', legend=False)
416
- plt.title(f'Top 10 Employees by Total Claim ({year})')
417
- plt.xlabel('Total Claim ($)')
418
- plt.ylabel('Employee')
 
419
  for i, v in enumerate(top_emp_claim['Total Claim (Combined)']):
420
- plt.text(v + 1, i, f'{v:,.2f}', va='center', fontsize=10, color='black')
421
  plt.tight_layout()
422
  employee_charts.append(plt.gcf())
423
  plt.close()
@@ -425,13 +422,14 @@ def generate_dashboard_charts(patient_data_by_year, claim_data_by_year, mc_data_
425
  # 3. Average Claim per Visit by Employees
426
  plt.figure(figsize=(12, 6))
427
  top_emp_avg_claim = patient_df.sort_values('Avg Claim per Visit', ascending=False).head(10)
428
- sns.barplot(data=top_emp_avg_claim, x='Employee Name', y='Avg Claim per Visit', hue='Employee Name', palette='Reds_d', legend=False)
429
- plt.title(f'Top 10 Employees by Avg Claim per Visit ({year})')
430
- plt.ylabel('Avg Claim per Visit ($)')
431
- plt.xlabel('Employee')
 
432
  plt.xticks(rotation=45, ha='right')
433
  for i, v in enumerate(top_emp_avg_claim['Avg Claim per Visit']):
434
- plt.text(i, v + 0.5, f'{v:.2f}', ha='center', fontsize=10, color='black')
435
  plt.tight_layout()
436
  employee_charts.append(plt.gcf())
437
  plt.close()
@@ -439,12 +437,13 @@ def generate_dashboard_charts(patient_data_by_year, claim_data_by_year, mc_data_
439
  # 4. Total MC by Employees
440
  plt.figure(figsize=(12, 6))
441
  top_emp_mc = patient_df.sort_values('Total MC (Days)', ascending=False).head(10)
442
- sns.barplot(data=top_emp_mc, x='Total MC (Days)', y='Employee Name', hue='Employee Name', palette='Greens_d', legend=False)
443
- plt.title(f'Top 10 Employees by Total MC ({year})')
444
- plt.xlabel('Total MC (Days)')
445
- plt.ylabel('Employee')
 
446
  for i, v in enumerate(top_emp_mc['Total MC (Days)']):
447
- plt.text(v + 0.2, i, f'{int(v)}', va='center', fontsize=10, color='black')
448
  plt.tight_layout()
449
  employee_charts.append(plt.gcf())
450
  plt.close()
@@ -452,36 +451,24 @@ def generate_dashboard_charts(patient_data_by_year, claim_data_by_year, mc_data_
452
  # 5. Average MC per Visit by Employees
453
  plt.figure(figsize=(12, 6))
454
  top_emp_avg_mc = patient_df.sort_values('Avg MC per Visit', ascending=False).head(10)
455
- sns.barplot(data=top_emp_avg_mc, x='Employee Name', y='Avg MC per Visit', hue='Employee Name', palette='Purples_d', legend=False)
456
- plt.title(f'Top 10 Employees by Avg MC per Visit ({year})')
457
- plt.ylabel('Avg MC per Visit (Days)')
458
- plt.xlabel('Employee')
 
459
  plt.xticks(rotation=45, ha='right')
460
  for i, v in enumerate(top_emp_avg_mc['Avg MC per Visit']):
461
- plt.text(i, v + 0.05, f'{v:.2f}', ha='center', fontsize=10, color='black')
462
- plt.tight_layout()
463
- employee_charts.append(plt.gcf())
464
- plt.close()
465
-
466
- # 6. Average Claim per MC by Employees
467
- plt.figure(figsize=(12, 6))
468
- top_emp_avg_claim_mc = patient_df.sort_values('Avg Claim per MC', ascending=False).head(10)
469
- sns.barplot(data=top_emp_avg_claim_mc, x='Employee Name', y='Avg Claim per MC', hue='Employee Name', palette='YlOrBr', legend=False)
470
- plt.title(f'Top 10 Employees by Avg Claim per MC ({year})')
471
- plt.ylabel('Avg Claim per MC ($)')
472
- plt.xlabel('Employee')
473
- plt.xticks(rotation=45, ha='right')
474
- for i, v in enumerate(top_emp_avg_claim_mc['Avg Claim per MC']):
475
- plt.text(i, v + 0.5, f'{v:.2f}', ha='center', fontsize=10, color='black')
476
  plt.tight_layout()
477
  employee_charts.append(plt.gcf())
478
  plt.close()
479
 
480
- # 7. Division-wise Claim Distribution (Pie)
481
  plt.figure(figsize=(10, 6))
482
  division_claims = patient_df.groupby('Division/Department')['Total Claim (Combined)'].sum()
483
- plt.pie(division_claims, labels=division_claims.index, autopct='%1.1f%%', colors=sns.color_palette('pastel'), startangle=90)
484
- plt.title(f'Claim Distribution by Division ({year})')
 
485
  plt.tight_layout()
486
  employee_charts.append(plt.gcf())
487
  plt.close()
@@ -500,14 +487,17 @@ def fig_to_image(fig):
500
  return img_array
501
 
502
  # --- Gradio Interface ---
503
- with gr.Blocks(title="Claims Analysis Dashboard") as demo:
 
 
 
504
  gr.Markdown("# Claims Analysis Dashboard (2024 - Present)")
505
 
506
  with gr.Row():
507
- url_input = gr.Textbox(label="Website URL")
508
- user_id_input = gr.Textbox(label="User ID")
509
- password_input = gr.Textbox(label="Password", type="password")
510
- scrape_btn = gr.Button("Scrape Data")
511
 
512
  with gr.Row():
513
  year_dropdown = gr.Dropdown(
@@ -517,8 +507,14 @@ with gr.Blocks(title="Claims Analysis Dashboard") as demo:
517
  allow_custom_value=False
518
  )
519
  show_mc_pct_checkbox = gr.Checkbox(label="Show % MC Given Chart", value=True)
 
 
 
 
 
 
520
 
521
- status_output = gr.Textbox(label="Status")
522
  patient_state = gr.State()
523
  claim_state = gr.State()
524
  mc_state = gr.State()
@@ -530,11 +526,10 @@ with gr.Blocks(title="Claims Analysis Dashboard") as demo:
530
  prov_chart1 = gr.Image(label="Total Visits by Providers", interactive=False)
531
  prov_chart2 = gr.Image(label="Total MC by Providers", interactive=False)
532
  with gr.Row():
533
- prov_chart3 = gr.Image(label="% MC Given by Providers", interactive=False, visible=True)
534
- prov_chart4 = gr.Image(label="Total Claim by Providers", interactive=False)
535
  with gr.Row():
 
536
  prov_chart5 = gr.Image(label="Average Claim per Visit by Providers", interactive=False)
537
- prov_chart6 = gr.Image(label="MC vs Claim Correlation", interactive=False)
538
 
539
  with gr.TabItem("Employee Insights"):
540
  gr.Markdown("## Employee Insights Dashboard")
@@ -546,57 +541,67 @@ with gr.Blocks(title="Claims Analysis Dashboard") as demo:
546
  emp_chart4 = gr.Image(label="Total MC by Employees", interactive=False)
547
  with gr.Row():
548
  emp_chart5 = gr.Image(label="Average MC per Visit by Employees", interactive=False)
549
- emp_chart6 = gr.Image(label="Average Claim per MC by Employees", interactive=False)
550
- with gr.Row():
551
- emp_chart7 = gr.Image(label="Claim Distribution by Division", interactive=False)
552
 
553
- def scrape_and_store(url, user_id, password, show_mc_pct):
 
554
  patient_data_by_year, claim_data_by_year, mc_data_by_year, status = scrape_data(url, user_id, password)
555
  if patient_data_by_year is None or claim_data_by_year is None or mc_data_by_year is None:
556
  return status, None, None, None
557
 
558
- provider_images, employee_images = generate_dashboard_charts(patient_data_by_year, claim_data_by_year, mc_data_by_year, "2024", show_mc_pct)
 
559
  return (
560
  status, patient_data_by_year, claim_data_by_year, mc_data_by_year,
561
- provider_images[0], provider_images[1], provider_images[2], provider_images[3], provider_images[4], provider_images[5],
562
- employee_images[0], employee_images[1], employee_images[2], employee_images[3], employee_images[4], employee_images[5], employee_images[6]
563
  )
564
 
565
- def update_dashboard(year, patient_data_by_year, claim_data_by_year, mc_data_by_year, show_mc_pct):
566
  if not patient_data_by_year or not claim_data_by_year or not mc_data_by_year:
567
- return [None] * 13
568
- provider_images, employee_images = generate_dashboard_charts(patient_data_by_year, claim_data_by_year, mc_data_by_year, year, show_mc_pct)
 
569
  return (
570
- provider_images[0], provider_images[1], provider_images[2], provider_images[3], provider_images[4], provider_images[5],
571
- employee_images[0], employee_images[1], employee_images[2], employee_images[3], employee_images[4], employee_images[5], employee_images[6]
572
  )
573
 
574
  scrape_btn.click(
575
- fn=lambda url, user_id, password: scrape_and_store(url, user_id, password, show_mc_pct_checkbox.value),
576
  inputs=[url_input, user_id_input, password_input],
577
  outputs=[
578
  status_output, patient_state, claim_state, mc_state,
579
- prov_chart1, prov_chart2, prov_chart3, prov_chart4, prov_chart5, prov_chart6,
580
- emp_chart1, emp_chart2, emp_chart3, emp_chart4, emp_chart5, emp_chart6, emp_chart7
581
  ]
582
  )
583
 
584
  year_dropdown.change(
585
  fn=update_dashboard,
586
- inputs=[year_dropdown, patient_state, claim_state, mc_state, show_mc_pct_checkbox],
587
  outputs=[
588
- prov_chart1, prov_chart2, prov_chart3, prov_chart4, prov_chart5, prov_chart6,
589
- emp_chart1, emp_chart2, emp_chart3, emp_chart4, emp_chart5, emp_chart6, emp_chart7
590
  ]
591
  )
592
 
593
  show_mc_pct_checkbox.change(
594
  fn=update_dashboard,
595
- inputs=[year_dropdown, patient_state, claim_state, mc_state, show_mc_pct_checkbox],
 
 
 
 
 
 
 
 
 
596
  outputs=[
597
- prov_chart1, prov_chart2, prov_chart3, prov_chart4, prov_chart5, prov_chart6,
598
- emp_chart1, emp_chart2, emp_chart3, emp_chart4, emp_chart5, emp_chart6, emp_chart7
599
  ]
600
  )
601
 
602
- demo.launch()
 
19
  return WebDriverWait(driver, 10).until(EC.element_to_be_clickable(locator))
20
 
21
  def select_date_month_day(driver, date_str, date_input_id):
22
+ date_to_select = datetime.strptime(date_str, '%Y-%m-%d')
23
  date_input = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.ID, date_input_id)))
24
  date_input.click()
25
  month_select = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.CLASS_NAME, 'ui-datepicker-month')))
 
287
 
288
 
289
  # --- Plotting Functions ---
290
+ def generate_dashboard_charts(patient_data_by_year, claim_data_by_year, mc_data_by_year, year, show_mc_pct=True, mc_sort_order="desc"):
291
  if not patient_data_by_year or not claim_data_by_year or not mc_data_by_year:
292
  return None, None
293
 
 
300
  return None, None
301
 
302
  # Professional styling
303
+ sns.set(style="whitegrid", palette="muted")
304
  plt.rcParams.update({
305
+ 'font.family': 'Helvetica', 'font.size': 12, 'axes.titlesize': 16,
306
+ 'axes.labelsize': 14, 'xtick.labelsize': 11, 'ytick.labelsize': 11,
307
+ 'axes.titleweight': 'bold', 'axes.linewidth': 1.5, 'grid.linestyle': ':',
308
+ 'grid.alpha': 0.5, 'figure.facecolor': '#f5f6f5', 'axes.facecolor': '#ffffff',
309
+ 'axes.edgecolor': '#333333', 'axes.labelcolor': '#333333', 'text.color': '#333333'
310
  })
311
 
312
  provider_charts = []
 
316
  # 1. Total Visits by Providers (Horizontal Bar)
317
  plt.figure(figsize=(12, 6))
318
  top_prov_visits = mc_df.sort_values('No. of Visit', ascending=False).head(10)
319
+ ax = sns.barplot(data=top_prov_visits, x='No. of Visit', y='Provider', hue='Provider', palette='Blues_r', legend=False, edgecolor='black', linewidth=0.5)
320
+ ax.set_title(f'Top 10 Providers by Total Visits ({year})', pad=15)
321
+ ax.set_xlabel('Total Visits')
322
+ ax.set_ylabel('Provider')
323
  for i, v in enumerate(top_prov_visits['No. of Visit']):
324
+ ax.text(v + 0.5, i, f'{int(v)}', va='center', fontsize=10, color='#333333')
325
  plt.tight_layout()
326
  provider_charts.append(plt.gcf())
327
  plt.close()
 
329
  # 2. Total MC by Providers (Horizontal Bar)
330
  plt.figure(figsize=(12, 6))
331
  top_prov_mc = mc_df.sort_values('Total MC Given', ascending=False).head(10)
332
+ ax = sns.barplot(data=top_prov_mc, x='Total MC Given', y='Provider', hue='Provider', palette='Greens_r', legend=False, edgecolor='black', linewidth=0.5)
333
+ ax.set_title(f'Top 10 Providers by Total MC Given ({year})', pad=15)
334
+ ax.set_xlabel('Total MC (Days)')
335
+ ax.set_ylabel('Provider')
336
  for i, v in enumerate(top_prov_mc['Total MC Given']):
337
+ ax.text(v + 0.5, i, f'{int(v)}', va='center', fontsize=10, color='#333333')
338
  plt.tight_layout()
339
  provider_charts.append(plt.gcf())
340
  plt.close()
341
 
342
+ # 3. % MC Given by Providers (Larger Bar, Top 20, Sortable)
343
  if show_mc_pct:
344
+ plt.figure(figsize=(18, 9)) # Larger size for professionalism and readability
345
  top_visits_provs = set(mc_df.sort_values('No. of Visit', ascending=False).head(10)['Provider'])
346
  top_mc_provs = set(mc_df.sort_values('Total MC Given', ascending=False).head(10)['Provider'])
347
  top_provs = top_visits_provs.union(top_mc_provs)
348
+ top_prov_mc_pct = mc_df[mc_df['Provider'].isin(top_provs)].sort_values(
349
+ '% MC Given', ascending=(mc_sort_order == "asc")).head(20)
350
+ ax = sns.barplot(data=top_prov_mc_pct, x='Provider', y='% MC Given', hue='Provider',
351
+ palette='Purples_r', legend=False, edgecolor='black', linewidth=0.5)
352
+ ax.set_title(f'Top 20 Providers by % MC Given ({year}) - Sorted {"Ascending" if mc_sort_order == "asc" else "Descending"}', pad=15)
353
+ ax.set_ylabel('% MC Given', fontsize=14)
354
+ ax.set_xlabel('Provider', fontsize=14)
355
+ plt.xticks(rotation=45, ha='right', fontsize=11)
356
  for i, v in enumerate(top_prov_mc_pct['% MC Given']):
357
+ ax.text(i, v + 1, f'{v:.1f}%', ha='center', fontsize=10, color='#333333')
358
  plt.tight_layout()
359
  provider_charts.append(plt.gcf())
360
  else:
 
364
  # 4. Total Claim by Providers (Horizontal Bar)
365
  plt.figure(figsize=(12, 6))
366
  top_prov_claim = claim_df.sort_values('Total Claim', ascending=False).head(10)
367
+ ax = sns.barplot(data=top_prov_claim, x='Total Claim', y='Provider Name', hue='Provider Name',
368
+ palette='Oranges_r', legend=False, edgecolor='black', linewidth=0.5)
369
+ ax.set_title(f'Top 10 Providers by Total Claim ({year})', pad=15)
370
+ ax.set_xlabel('Total Claim ($)')
371
+ ax.set_ylabel('Provider')
372
  for i, v in enumerate(top_prov_claim['Total Claim']):
373
+ ax.text(v + 0.5, i, f'{v:,.2f}', va='center', fontsize=10, color='#333333')
374
  plt.tight_layout()
375
  provider_charts.append(plt.gcf())
376
  plt.close()
 
378
  # 5. Average Claim per Visit by Providers (Bar)
379
  plt.figure(figsize=(12, 6))
380
  top_prov_avg_claim = claim_df.sort_values('Avg Claim per Visit', ascending=False).head(10)
381
+ ax = sns.barplot(data=top_prov_avg_claim, x='Provider Name', y='Avg Claim per Visit', hue='Provider Name',
382
+ palette='Reds_r', legend=False, edgecolor='black', linewidth=0.5)
383
+ ax.set_title(f'Top 10 Providers by Avg Claim per Visit ({year})', pad=15)
384
+ ax.set_ylabel('Avg Claim per Visit ($)')
385
+ ax.set_xlabel('Provider')
386
  plt.xticks(rotation=45, ha='right')
387
  for i, v in enumerate(top_prov_avg_claim['Avg Claim per Visit']):
388
+ ax.text(i, v + 0.5, f'{v:.2f}', ha='center', fontsize=10, color='#333333')
 
 
 
 
 
 
 
 
 
 
389
  plt.tight_layout()
390
  provider_charts.append(plt.gcf())
391
  plt.close()
392
 
393
+ # --- Employee Dashboard Charts ---
394
  # 1. Total Visits by Employees
395
  plt.figure(figsize=(12, 6))
396
  top_emp_visits = patient_df.sort_values('Total Visit', ascending=False).head(10)
397
+ ax = sns.barplot(data=top_emp_visits, x='Total Visit', y='Employee Name', hue='Employee Name',
398
+ palette='Blues_r', legend=False, edgecolor='black', linewidth=0.5)
399
+ ax.set_title(f'Top 10 Employees by Total Visits ({year})', pad=15)
400
+ ax.set_xlabel('Total Visits')
401
+ ax.set_ylabel('Employee')
402
  for i, v in enumerate(top_emp_visits['Total Visit']):
403
+ ax.text(v + 0.2, i, f'{int(v)}', va='center', fontsize=10, color='#333333')
404
  plt.tight_layout()
405
  employee_charts.append(plt.gcf())
406
  plt.close()
 
408
  # 2. Total Claim by Employees
409
  plt.figure(figsize=(12, 6))
410
  top_emp_claim = patient_df.sort_values('Total Claim (Combined)', ascending=False).head(10)
411
+ ax = sns.barplot(data=top_emp_claim, x='Total Claim (Combined)', y='Employee Name', hue='Employee Name',
412
+ palette='Oranges_r', legend=False, edgecolor='black', linewidth=0.5)
413
+ ax.set_title(f'Top 10 Employees by Total Claim ({year})', pad=15)
414
+ ax.set_xlabel('Total Claim ($)')
415
+ ax.set_ylabel('Employee')
416
  for i, v in enumerate(top_emp_claim['Total Claim (Combined)']):
417
+ ax.text(v + 1, i, f'{v:,.2f}', va='center', fontsize=10, color='#333333')
418
  plt.tight_layout()
419
  employee_charts.append(plt.gcf())
420
  plt.close()
 
422
  # 3. Average Claim per Visit by Employees
423
  plt.figure(figsize=(12, 6))
424
  top_emp_avg_claim = patient_df.sort_values('Avg Claim per Visit', ascending=False).head(10)
425
+ ax = sns.barplot(data=top_emp_avg_claim, x='Employee Name', y='Avg Claim per Visit', hue='Employee Name',
426
+ palette='Reds_r', legend=False, edgecolor='black', linewidth=0.5)
427
+ ax.set_title(f'Top 10 Employees by Avg Claim per Visit ({year})', pad=15)
428
+ ax.set_ylabel('Avg Claim per Visit ($)')
429
+ ax.set_xlabel('Employee')
430
  plt.xticks(rotation=45, ha='right')
431
  for i, v in enumerate(top_emp_avg_claim['Avg Claim per Visit']):
432
+ ax.text(i, v + 0.5, f'{v:.2f}', ha='center', fontsize=10, color='#333333')
433
  plt.tight_layout()
434
  employee_charts.append(plt.gcf())
435
  plt.close()
 
437
  # 4. Total MC by Employees
438
  plt.figure(figsize=(12, 6))
439
  top_emp_mc = patient_df.sort_values('Total MC (Days)', ascending=False).head(10)
440
+ ax = sns.barplot(data=top_emp_mc, x='Total MC (Days)', y='Employee Name', hue='Employee Name',
441
+ palette='Greens_r', legend=False, edgecolor='black', linewidth=0.5)
442
+ ax.set_title(f'Top 10 Employees by Total MC ({year})', pad=15)
443
+ ax.set_xlabel('Total MC (Days)')
444
+ ax.set_ylabel('Employee')
445
  for i, v in enumerate(top_emp_mc['Total MC (Days)']):
446
+ ax.text(v + 0.2, i, f'{int(v)}', va='center', fontsize=10, color='#333333')
447
  plt.tight_layout()
448
  employee_charts.append(plt.gcf())
449
  plt.close()
 
451
  # 5. Average MC per Visit by Employees
452
  plt.figure(figsize=(12, 6))
453
  top_emp_avg_mc = patient_df.sort_values('Avg MC per Visit', ascending=False).head(10)
454
+ ax = sns.barplot(data=top_emp_avg_mc, x='Employee Name', y='Avg MC per Visit', hue='Employee Name',
455
+ palette='Purples_r', legend=False, edgecolor='black', linewidth=0.5)
456
+ ax.set_title(f'Top 10 Employees by Avg MC per Visit ({year})', pad=15)
457
+ ax.set_ylabel('Avg MC per Visit (Days)')
458
+ ax.set_xlabel('Employee')
459
  plt.xticks(rotation=45, ha='right')
460
  for i, v in enumerate(top_emp_avg_mc['Avg MC per Visit']):
461
+ ax.text(i, v + 0.05, f'{v:.2f}', ha='center', fontsize=10, color='#333333')
 
 
 
 
 
 
 
 
 
 
 
 
 
 
462
  plt.tight_layout()
463
  employee_charts.append(plt.gcf())
464
  plt.close()
465
 
466
+ # 6. Division-wise Claim Distribution (Pie)
467
  plt.figure(figsize=(10, 6))
468
  division_claims = patient_df.groupby('Division/Department')['Total Claim (Combined)'].sum()
469
+ plt.pie(division_claims, labels=division_claims.index, autopct='%1.1f%%', colors=sns.color_palette('muted'),
470
+ startangle=90, textprops={'fontsize': 11, 'color': '#333333'}, wedgeprops={'edgecolor': 'black', 'linewidth': 0.5})
471
+ plt.title(f'Claim Distribution by Division ({year})', pad=15)
472
  plt.tight_layout()
473
  employee_charts.append(plt.gcf())
474
  plt.close()
 
487
  return img_array
488
 
489
  # --- Gradio Interface ---
490
+ with gr.Blocks(title="Claims Analysis Dashboard", css="""
491
+ body { background-color: #f5f6f5; }
492
+ h1, h2 { color: #333333; font-family: Helvetica; }
493
+ """) as demo:
494
  gr.Markdown("# Claims Analysis Dashboard (2024 - Present)")
495
 
496
  with gr.Row():
497
+ url_input = gr.Textbox(label="Website URL", placeholder="Enter URL here", lines=1)
498
+ user_id_input = gr.Textbox(label="User ID", placeholder="Enter User ID", lines=1)
499
+ password_input = gr.Textbox(label="Password", type="password", placeholder="Enter Password", lines=1)
500
+ scrape_btn = gr.Button("Submit", variant="primary")
501
 
502
  with gr.Row():
503
  year_dropdown = gr.Dropdown(
 
507
  allow_custom_value=False
508
  )
509
  show_mc_pct_checkbox = gr.Checkbox(label="Show % MC Given Chart", value=True)
510
+ mc_sort_dropdown = gr.Dropdown(
511
+ label="Sort % MC Given",
512
+ choices=["desc", "asc"],
513
+ value="desc",
514
+ allow_custom_value=False
515
+ )
516
 
517
+ status_output = gr.Textbox(label="Status", lines=2, interactive=False)
518
  patient_state = gr.State()
519
  claim_state = gr.State()
520
  mc_state = gr.State()
 
526
  prov_chart1 = gr.Image(label="Total Visits by Providers", interactive=False)
527
  prov_chart2 = gr.Image(label="Total MC by Providers", interactive=False)
528
  with gr.Row():
529
+ prov_chart3 = gr.Image(label="% MC Given by Providers (Top 20)", interactive=False, visible=True)
 
530
  with gr.Row():
531
+ prov_chart4 = gr.Image(label="Total Claim by Providers", interactive=False)
532
  prov_chart5 = gr.Image(label="Average Claim per Visit by Providers", interactive=False)
 
533
 
534
  with gr.TabItem("Employee Insights"):
535
  gr.Markdown("## Employee Insights Dashboard")
 
541
  emp_chart4 = gr.Image(label="Total MC by Employees", interactive=False)
542
  with gr.Row():
543
  emp_chart5 = gr.Image(label="Average MC per Visit by Employees", interactive=False)
544
+ emp_chart6 = gr.Image(label="Claim Distribution by Division", interactive=False)
 
 
545
 
546
+ # [Event handlers remain unchanged, just ensure inputs/outputs match the above components]
547
+ def scrape_and_store(url, user_id, password, show_mc_pct, mc_sort_order):
548
  patient_data_by_year, claim_data_by_year, mc_data_by_year, status = scrape_data(url, user_id, password)
549
  if patient_data_by_year is None or claim_data_by_year is None or mc_data_by_year is None:
550
  return status, None, None, None
551
 
552
+ provider_images, employee_images = generate_dashboard_charts(
553
+ patient_data_by_year, claim_data_by_year, mc_data_by_year, "2024", show_mc_pct, mc_sort_order)
554
  return (
555
  status, patient_data_by_year, claim_data_by_year, mc_data_by_year,
556
+ provider_images[0], provider_images[1], provider_images[2], provider_images[3], provider_images[4],
557
+ employee_images[0], employee_images[1], employee_images[2], employee_images[3], employee_images[4], employee_images[5]
558
  )
559
 
560
+ def update_dashboard(year, patient_data_by_year, claim_data_by_year, mc_data_by_year, show_mc_pct, mc_sort_order):
561
  if not patient_data_by_year or not claim_data_by_year or not mc_data_by_year:
562
+ return [None] * 11
563
+ provider_images, employee_images = generate_dashboard_charts(
564
+ patient_data_by_year, claim_data_by_year, mc_data_by_year, year, show_mc_pct, mc_sort_order)
565
  return (
566
+ provider_images[0], provider_images[1], provider_images[2], provider_images[3], provider_images[4],
567
+ employee_images[0], employee_images[1], employee_images[2], employee_images[3], employee_images[4], employee_images[5]
568
  )
569
 
570
  scrape_btn.click(
571
+ fn=lambda url, user_id, password: scrape_and_store(url, user_id, password, show_mc_pct_checkbox.value, mc_sort_dropdown.value),
572
  inputs=[url_input, user_id_input, password_input],
573
  outputs=[
574
  status_output, patient_state, claim_state, mc_state,
575
+ prov_chart1, prov_chart2, prov_chart3, prov_chart4, prov_chart5,
576
+ emp_chart1, emp_chart2, emp_chart3, emp_chart4, emp_chart5, emp_chart6
577
  ]
578
  )
579
 
580
  year_dropdown.change(
581
  fn=update_dashboard,
582
+ inputs=[year_dropdown, patient_state, claim_state, mc_state, show_mc_pct_checkbox, mc_sort_dropdown],
583
  outputs=[
584
+ prov_chart1, prov_chart2, prov_chart3, prov_chart4, prov_chart5,
585
+ emp_chart1, emp_chart2, emp_chart3, emp_chart4, emp_chart5, emp_chart6
586
  ]
587
  )
588
 
589
  show_mc_pct_checkbox.change(
590
  fn=update_dashboard,
591
+ inputs=[year_dropdown, patient_state, claim_state, mc_state, show_mc_pct_checkbox, mc_sort_dropdown],
592
+ outputs=[
593
+ prov_chart1, prov_chart2, prov_chart3, prov_chart4, prov_chart5,
594
+ emp_chart1, emp_chart2, emp_chart3, emp_chart4, emp_chart5, emp_chart6
595
+ ]
596
+ )
597
+
598
+ mc_sort_dropdown.change(
599
+ fn=update_dashboard,
600
+ inputs=[year_dropdown, patient_state, claim_state, mc_state, show_mc_pct_checkbox, mc_sort_dropdown],
601
  outputs=[
602
+ prov_chart1, prov_chart2, prov_chart3, prov_chart4, prov_chart5,
603
+ emp_chart1, emp_chart2, emp_chart3, emp_chart4, emp_chart5, emp_chart6
604
  ]
605
  )
606
 
607
+ demo.launch(share=True)