Wajahat698 commited on
Commit
2a2e2b7
·
verified ·
1 Parent(s): 7cced23

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +73 -47
app.py CHANGED
@@ -377,86 +377,112 @@ def call_r_script(
377
 
378
 
379
 
380
- def plot_trust_driver_bubbles(trust_df, title):
 
 
 
 
 
 
 
 
 
381
  """
382
- Creates a bubble plot for Trust Drivers using preset positions and colors.
383
-
 
384
  Args:
385
- trust_df (DataFrame): DataFrame containing Trust driver data with an "Importance_percent" column.
386
  title (str): Title of the plot.
387
-
 
 
388
  Returns:
389
- Image: PIL Image of the bubble plot.
390
  """
391
- # Set the background image path
392
  image_path = "./images/image.png"
393
-
394
- # Load background image
395
  try:
396
- img = Image.open(image_path)
397
  except FileNotFoundError:
398
- raise FileNotFoundError(f"❌ Error: Background image '{image_path}' not found!")
399
 
400
- # Define the fixed bubble order (for Trust Drivers)
401
  bubble_order = ["Vision", "Development", "Benefit", "Competence", "Stability", "Relationship"]
402
-
403
- # Colors for each bubble (in the same order)
404
  colors = ["#DF8859", "#E3B05B", "#418387", "#6D93AB", "#375570", "#C63F48"]
405
 
406
- # Bubble positions (aligned with the background image)
407
- bubble_positions = [
408
- (0.66, 1.20), # Vision Trust (Moved Up)
409
- (1.43, -0.08), # Development Trust (Kept Similar)
410
- (0.66, -1.10), # Benefit Trust (Kept Similar)
411
- (-0.70, -1.20), # Competence Trust (Kept Similar)
412
- (-1.30, -0.08), # Stability Trust (Kept Similar)
413
- (-0.70, 1.15) # Relationship Trust (Shifted Left)
414
- ]
415
-
416
- # Extract importance percentages for each predictor.
417
- # If a predictor is missing, default to 0.
418
  values_dict = trust_df.set_index("Predictor")["Importance_percent"].to_dict()
419
  percentages = [values_dict.get(pred, 0) for pred in bubble_order]
420
 
421
- # Scale bubble sizes dynamically based on the percentages
422
- max_size = 0.30 # Maximum bubble size
423
- min_size = 0.23 # Minimum bubble size
424
- min_value, max_value = min(percentages), max(percentages)
425
- bubble_sizes = [
426
- min_size + (max_size - min_size) * ((p - min_value) / (max_value - min_value + 1e-5))
 
427
  for p in percentages
428
  ]
429
 
430
- # Create the figure and axis
431
- fig, ax = plt.subplots(figsize=(8, 8))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
432
  ax.set_xlim(-2, 2)
433
  ax.set_ylim(-2, 2)
434
- ax.set_aspect('equal') # Lock the aspect ratio
435
  ax.axis("off")
436
 
437
- # Display the background image (ensure the extent aligns with your coordinate system)
438
- ax.imshow(img, extent=[-1.5, 1.5, -1.5, 1.5])
 
 
 
 
 
 
439
 
440
- # Draw bubbles and add centered percentage text
441
- for i, (x, y) in enumerate(bubble_positions):
442
- size = bubble_sizes[i]
443
- circle = patches.Circle((x, y), size, facecolor=colors[i], alpha=1.0, lw=1.5)
444
  ax.add_patch(circle)
 
 
445
  ax.text(
446
- x, y, f"{percentages[i]:.1f}%", fontsize=12, fontweight="bold",
447
- ha="center", va="center", color="white"
448
  )
449
 
450
- # Optionally, add a title (if desired)
451
- plt.title(title, fontsize=14)
452
 
453
- # Save the plot to a bytes buffer and return a PIL Image
454
  img_buffer = io.BytesIO()
455
  plt.savefig(img_buffer, format="png", bbox_inches="tight", facecolor=fig.get_facecolor())
456
  img_buffer.seek(0)
457
  plt.close(fig)
458
- return Image.open(img_buffer)
459
 
 
460
 
461
 
462
  def analyze_excel_single(file_path):
 
377
 
378
 
379
 
380
+ import matplotlib.pyplot as plt
381
+ import matplotlib.patches as patches
382
+ from PIL import Image
383
+ import numpy as np
384
+ import pandas as pd
385
+ import io
386
+ import math
387
+ import os
388
+
389
+ def plot_trust_driver_bubbles(trust_df, title, bubble_positions=None, gap=-0.2):
390
  """
391
+ Creates a bubble plot for Trust Drivers ensuring that all bubbles are proportionate in size (e.g., 20% is twice the area of 10%)
392
+ and slightly touch the Trust Core without overlapping.
393
+
394
  Args:
395
+ trust_df (DataFrame): DataFrame with columns "Predictor" and "Importance_percent".
396
  title (str): Title of the plot.
397
+ bubble_positions (dict, optional): Custom (x, y) positions for each trust driver.
398
+ gap (float): Fine-tuning for spacing around Trust Core.
399
+
400
  Returns:
401
+ PIL.Image: Final image with plotted bubbles and Trust Core.
402
  """
403
+ # Load Trust Core image
404
  image_path = "./images/image.png"
 
 
405
  try:
406
+ trust_core_img = Image.open(image_path)
407
  except FileNotFoundError:
408
+ raise FileNotFoundError(f"❌ Error: Trust Core image '{image_path}' not found!")
409
 
410
+ # Define bubble order and colors
411
  bubble_order = ["Vision", "Development", "Benefit", "Competence", "Stability", "Relationship"]
 
 
412
  colors = ["#DF8859", "#E3B05B", "#418387", "#6D93AB", "#375570", "#C63F48"]
413
 
414
+ # Extract percentages
 
 
 
 
 
 
 
 
 
 
 
415
  values_dict = trust_df.set_index("Predictor")["Importance_percent"].to_dict()
416
  percentages = [values_dict.get(pred, 0) for pred in bubble_order]
417
 
418
+ # Base for scaling (min value gets min_radius)
419
+ base_percentage = min(percentages) if min(percentages) > 0 else 1
420
+ min_radius = 0.18 # radius for the smallest bubble
421
+
422
+ # 🔧 Area-proportional radius calculation
423
+ bubble_radii = [
424
+ min_radius * math.sqrt(p / base_percentage)
425
  for p in percentages
426
  ]
427
 
428
+ # Central core radius (for image and collision checking)
429
+ central_radius = 0.8
430
+
431
+ # Default layout positions (can be overridden)
432
+ default_positions = {
433
+ "Vision": (0.6, 0.85),
434
+ "Development": (1.05, 0.0),
435
+ "Benefit": (0.6, -0.85),
436
+ "Competence": (-0.6, -0.85),
437
+ "Stability": (-1.05, 0.0),
438
+ "Relationship": (-0.6, 0.85)
439
+ }
440
+ bubble_positions = bubble_positions if bubble_positions else default_positions.copy()
441
+
442
+ # Adjust positions to ensure bubbles touch the Trust Core
443
+ for i, trust_driver in enumerate(bubble_order):
444
+ x, y = bubble_positions[trust_driver]
445
+ bubble_radius = bubble_radii[i]
446
+ distance_to_core = np.sqrt(x**2 + y**2)
447
+ scale_factor = (central_radius + bubble_radius + gap) / distance_to_core
448
+ bubble_positions[trust_driver] = (x * scale_factor, y * scale_factor)
449
+
450
+ # Plot setup
451
+ fig, ax = plt.subplots(figsize=(10, 10), dpi=300)
452
  ax.set_xlim(-2, 2)
453
  ax.set_ylim(-2, 2)
454
+ ax.set_aspect('equal')
455
  ax.axis("off")
456
 
457
+ # Draw Trust Core image
458
+ extent = [-central_radius, central_radius, -central_radius, central_radius]
459
+ ax.imshow(trust_core_img, extent=extent, alpha=1.0)
460
+
461
+ # Draw bubbles and text
462
+ for i, trust_driver in enumerate(bubble_order):
463
+ x, y = bubble_positions[trust_driver]
464
+ radius = bubble_radii[i]
465
 
466
+ # Draw bubble
467
+ circle = patches.Circle((x, y), radius, facecolor=colors[i], edgecolor='white', lw=1.5)
 
 
468
  ax.add_patch(circle)
469
+
470
+ # Text inside bubble
471
  ax.text(
472
+ x, y, f"{trust_driver.upper()}\n{percentages[i]:.1f}%",
473
+ fontsize=8.5, fontweight="bold", ha="center", va="center", color="white"
474
  )
475
 
476
+ # Title
477
+ plt.title(title, fontsize=12)
478
 
479
+ # Export to image
480
  img_buffer = io.BytesIO()
481
  plt.savefig(img_buffer, format="png", bbox_inches="tight", facecolor=fig.get_facecolor())
482
  img_buffer.seek(0)
483
  plt.close(fig)
 
484
 
485
+ return Image.open(img_buffer)
486
 
487
 
488
  def analyze_excel_single(file_path):