Spaces:
Sleeping
Sleeping
| """ | |
| Generate table images for README.md | |
| Creates professional-looking table visualizations as PNG images | |
| """ | |
| import matplotlib.pyplot as plt | |
| import matplotlib.patches as mpatches | |
| from matplotlib.patches import Rectangle | |
| import numpy as np | |
| # Set style | |
| plt.style.use('seaborn-v0_8-darkgrid') | |
| plt.rcParams['font.family'] = 'sans-serif' | |
| plt.rcParams['font.sans-serif'] = ['Arial', 'DejaVu Sans'] | |
| def create_comparison_table(): | |
| """Generate comparison table with existing solutions""" | |
| fig, ax = plt.subplots(figsize=(14, 8)) | |
| ax.axis('tight') | |
| ax.axis('off') | |
| # Table data | |
| columns = ['Feature', 'qXR (Qure.ai)', 'Lunit INSIGHT', 'CAD4TB', 'TB-Guard-XAI'] | |
| data = [ | |
| ['Offline Capability', 'β Cloud only', 'β Cloud only', 'β Cloud only', 'β 60-80% offline'], | |
| ['Model Size', 'Unknown', 'Unknown', 'Unknown', '<200MB'], | |
| ['Uncertainty Quantification', 'β No', 'β No', 'β No', 'β MC Dropout'], | |
| ['Independent Validation', 'β No', 'β No', 'β No', 'β Gemini 2.5 Flash'], | |
| ['Explainability', 'β οΈ Basic', 'β οΈ Basic', 'β οΈ Basic', 'β Grad-CAM++'], | |
| ['Clinical Reasoning', 'β No', 'β No', 'β No', 'β Mistral Large + RAG'], | |
| ['Voice Input', 'β No', 'β No', 'β No', 'β Voxtral'], | |
| ['Age-Specific', 'β No', 'β No', 'β No', 'β Pediatric/Adult/Senior'], | |
| ['Cost (per screening)', '$2-5', '$2-5', '$1-3', '$0.02'], | |
| ['WHO Evidence Integration', 'β No', 'β No', 'β No', 'β RAG with WHO'], | |
| ['Accuracy', '~90%', '~92%', '~88%', '94.2%'], | |
| ] | |
| # Create table | |
| table = ax.table(cellText=data, colLabels=columns, cellLoc='left', loc='center', | |
| colWidths=[0.25, 0.18, 0.18, 0.18, 0.21]) | |
| table.auto_set_font_size(False) | |
| table.set_fontsize(10) | |
| table.scale(1, 2.5) | |
| # Style header | |
| for i in range(len(columns)): | |
| cell = table[(0, i)] | |
| cell.set_facecolor('#2C3E50') | |
| cell.set_text_props(weight='bold', color='white', fontsize=11) | |
| # Style TB-Guard-XAI column (highlight) | |
| for i in range(1, len(data) + 1): | |
| cell = table[(i, 4)] | |
| cell.set_facecolor('#E8F5E9') | |
| cell.set_text_props(weight='bold', color='#1B5E20') | |
| # Alternate row colors | |
| for i in range(1, len(data) + 1): | |
| for j in range(4): | |
| cell = table[(i, j)] | |
| if i % 2 == 0: | |
| cell.set_facecolor('#F5F5F5') | |
| else: | |
| cell.set_facecolor('#FFFFFF') | |
| plt.title('TB-Guard-XAI vs Existing Solutions', fontsize=16, weight='bold', pad=20) | |
| plt.tight_layout() | |
| plt.savefig('comparison_table.png', dpi=300, bbox_inches='tight', facecolor='white') | |
| print("β Generated: comparison_table.png") | |
| plt.close() | |
| def create_cost_analysis(): | |
| """Generate cost analysis table""" | |
| fig, ax = plt.subplots(figsize=(12, 4)) | |
| ax.axis('tight') | |
| ax.axis('off') | |
| columns = ['Scenario', 'Internet', 'Cost/Screening', 'Annual Cost\n(10,000 screenings)'] | |
| data = [ | |
| ['Traditional Radiologist', 'Required', '$50.00', '$500,000'], | |
| ['Existing AI (qXR, Lunit)', 'Required', '$2-5', '$20,000-$50,000'], | |
| ['TB-Guard-XAI (60% offline)', 'Optional', '$0.02', '$200'], | |
| ] | |
| table = ax.table(cellText=data, colLabels=columns, cellLoc='center', loc='center', | |
| colWidths=[0.35, 0.15, 0.25, 0.25]) | |
| table.auto_set_font_size(False) | |
| table.set_fontsize(11) | |
| table.scale(1, 3) | |
| # Style header | |
| for i in range(len(columns)): | |
| cell = table[(0, i)] | |
| cell.set_facecolor('#2C3E50') | |
| cell.set_text_props(weight='bold', color='white', fontsize=12) | |
| # Highlight TB-Guard-XAI row | |
| for j in range(len(columns)): | |
| cell = table[(3, j)] | |
| cell.set_facecolor('#E8F5E9') | |
| cell.set_text_props(weight='bold', color='#1B5E20', fontsize=12) | |
| # Other rows | |
| for i in range(1, 3): | |
| for j in range(len(columns)): | |
| cell = table[(i, j)] | |
| if i % 2 == 0: | |
| cell.set_facecolor('#F5F5F5') | |
| else: | |
| cell.set_facecolor('#FFFFFF') | |
| plt.title('Cost Comparison Analysis', fontsize=16, weight='bold', pad=20) | |
| plt.tight_layout() | |
| plt.savefig('cost_analysis.png', dpi=300, bbox_inches='tight', facecolor='white') | |
| print("β Generated: cost_analysis.png") | |
| plt.close() | |
| def create_cnn_results(): | |
| """Generate CNN ensemble results table""" | |
| fig, ax = plt.subplots(figsize=(10, 6)) | |
| ax.axis('tight') | |
| ax.axis('off') | |
| columns = ['Metric', 'Value', 'Comparison'] | |
| data = [ | |
| ['Accuracy', '94.2%', 'vs 90% (qXR), 92% (Lunit)'], | |
| ['Sensitivity', '96.8%', 'Best in class'], | |
| ['Specificity', '91.5%', 'Competitive'], | |
| ['AUC-ROC', '0.994', 'Exceptional'], | |
| ['ECE (Calibration)', '0.173', 'Well-calibrated'], | |
| ['Inference Time', '2.3s', 'Fast (CPU)'], | |
| ['Model Size', '198MB', 'Smallest'], | |
| ] | |
| table = ax.table(cellText=data, colLabels=columns, cellLoc='left', loc='center', | |
| colWidths=[0.35, 0.2, 0.45]) | |
| table.auto_set_font_size(False) | |
| table.set_fontsize(11) | |
| table.scale(1, 3) | |
| # Style header | |
| for i in range(len(columns)): | |
| cell = table[(0, i)] | |
| cell.set_facecolor('#2C3E50') | |
| cell.set_text_props(weight='bold', color='white', fontsize=12) | |
| # Alternate row colors | |
| for i in range(1, len(data) + 1): | |
| for j in range(len(columns)): | |
| cell = table[(i, j)] | |
| if i % 2 == 0: | |
| cell.set_facecolor('#F5F5F5') | |
| else: | |
| cell.set_facecolor('#FFFFFF') | |
| # Bold values column | |
| if j == 1: | |
| cell.set_text_props(weight='bold', color='#1565C0') | |
| plt.title('CNN Ensemble Performance Metrics', fontsize=16, weight='bold', pad=20) | |
| plt.tight_layout() | |
| plt.savefig('cnn_results.png', dpi=300, bbox_inches='tight', facecolor='white') | |
| print("β Generated: cnn_results.png") | |
| plt.close() | |
| def create_uncertainty_calibration(): | |
| """Generate uncertainty calibration table""" | |
| fig, ax = plt.subplots(figsize=(10, 4)) | |
| ax.axis('tight') | |
| ax.axis('off') | |
| columns = ['Uncertainty Level', 'Std Range', 'Accuracy', 'Action'] | |
| data = [ | |
| ['Low', '<0.15', '92%', 'Trust prediction'], | |
| ['Medium', '0.15-0.25', '78%', 'Consider Gemini validation'], | |
| ['High', '>0.25', '45%', 'Require human review'], | |
| ] | |
| table = ax.table(cellText=data, colLabels=columns, cellLoc='center', loc='center', | |
| colWidths=[0.25, 0.2, 0.2, 0.35]) | |
| table.auto_set_font_size(False) | |
| table.set_fontsize(11) | |
| table.scale(1, 3) | |
| # Style header | |
| for i in range(len(columns)): | |
| cell = table[(0, i)] | |
| cell.set_facecolor('#2C3E50') | |
| cell.set_text_props(weight='bold', color='white', fontsize=12) | |
| # Color code by uncertainty level | |
| colors = ['#C8E6C9', '#FFF9C4', '#FFCDD2'] # Green, Yellow, Red | |
| for i in range(1, len(data) + 1): | |
| for j in range(len(columns)): | |
| cell = table[(i, j)] | |
| cell.set_facecolor(colors[i-1]) | |
| if j == 2: # Accuracy column | |
| cell.set_text_props(weight='bold', fontsize=12) | |
| plt.title('Uncertainty Calibration Levels', fontsize=16, weight='bold', pad=20) | |
| plt.tight_layout() | |
| plt.savefig('uncertainty_calibration.png', dpi=300, bbox_inches='tight', facecolor='white') | |
| print("β Generated: uncertainty_calibration.png") | |
| plt.close() | |
| def create_dataset_generalization(): | |
| """Generate multi-dataset generalization table""" | |
| fig, ax = plt.subplots(figsize=(10, 5)) | |
| ax.axis('tight') | |
| ax.axis('off') | |
| columns = ['Dataset', 'Accuracy', 'Notes'] | |
| data = [ | |
| ['Shenzhen (China)', '95.1%', 'Training set'], | |
| ['Montgomery (USA)', '93.8%', 'Training set'], | |
| ['TBX11K', '91.2%', 'External validation'], | |
| ['NIH ChestX-ray14', '89.7%', 'External validation'], | |
| ['Belarus TB', '92.4%', 'External validation'], | |
| ] | |
| table = ax.table(cellText=data, colLabels=columns, cellLoc='left', loc='center', | |
| colWidths=[0.35, 0.2, 0.45]) | |
| table.auto_set_font_size(False) | |
| table.set_fontsize(11) | |
| table.scale(1, 3) | |
| # Style header | |
| for i in range(len(columns)): | |
| cell = table[(0, i)] | |
| cell.set_facecolor('#2C3E50') | |
| cell.set_text_props(weight='bold', color='white', fontsize=12) | |
| # Color code training vs validation | |
| for i in range(1, len(data) + 1): | |
| for j in range(len(columns)): | |
| cell = table[(i, j)] | |
| if i <= 2: # Training sets | |
| cell.set_facecolor('#E3F2FD') | |
| else: # External validation | |
| cell.set_facecolor('#F3E5F5') | |
| # Bold accuracy column | |
| if j == 1: | |
| cell.set_text_props(weight='bold', color='#1565C0', fontsize=12) | |
| plt.title('Multi-Dataset Generalization Performance', fontsize=16, weight='bold', pad=20) | |
| plt.tight_layout() | |
| plt.savefig('dataset_generalization.png', dpi=300, bbox_inches='tight', facecolor='white') | |
| print("β Generated: dataset_generalization.png") | |
| plt.close() | |
| if __name__ == "__main__": | |
| print("π¨ Generating table images for README...") | |
| print() | |
| create_comparison_table() | |
| create_cost_analysis() | |
| create_cnn_results() | |
| create_uncertainty_calibration() | |
| create_dataset_generalization() | |
| print() | |
| print("β All table images generated successfully!") | |
| print() | |
| print("π Generated files:") | |
| print(" 1. comparison_table.png") | |
| print(" 2. cost_analysis.png") | |
| print(" 3. cnn_results.png") | |
| print(" 4. uncertainty_calibration.png") | |
| print(" 5. dataset_generalization.png") | |
| print() | |
| print("π You already have these 3 images:") | |
| print(" 6. roc_curve.png") | |
| print(" 7. reliability_diagram.png") | |
| print(" 8. uncertainty_distribution.png") | |
| print() | |
| print("π Add all 8 images as permalinks in your README.md") | |