import gradio as gr import pandas as pd import numpy as np import matplotlib.pyplot as plt import seaborn as sns from matplotlib.patches import Rectangle import io import warnings warnings.filterwarnings('ignore') # Set style for better plots plt.style.use('default') sns.set_palette("husl") def load_and_display_data(file): """Load CSV file and return dataframe""" if file is None: return None, "Please upload a CSV file" try: df = pd.read_csv(file) return df, f"Data loaded successfully! Shape: {df.shape}" except Exception as e: return None, f"Error loading file: {str(e)}" def sort_dataframe(df, sort_column, ascending=True): """Sort dataframe by selected column""" if df is None or df.empty: return df if sort_column not in df.columns: return df try: return df.sort_values(by=sort_column, ascending=ascending) except: return df def create_bar_plot(df, column_name, title_suffix=""): """Create bar plot for AUC, R-square, or p-values""" if df is None or df.empty or column_name not in df.columns: fig, ax = plt.subplots(figsize=(10, 6)) ax.text(0.5, 0.5, f'Column "{column_name}" not found in data', ha='center', va='center', transform=ax.transAxes) return fig # Filter out missing values plot_df = df[df[column_name].notna()].copy() if plot_df.empty: fig, ax = plt.subplots(figsize=(10, 6)) ax.text(0.5, 0.5, f'No valid data for "{column_name}"', ha='center', va='center', transform=ax.transAxes) return fig # Group by predictor and take mean if multiple values if 'predictor' in plot_df.columns: plot_df = plot_df.groupby('predictor')[column_name].mean().reset_index() # Sort by value plot_df = plot_df.sort_values(column_name, ascending=True) # Create plot fig, ax = plt.subplots(figsize=(12, max(6, len(plot_df) * 0.3))) bars = ax.barh(range(len(plot_df)), plot_df[column_name], color='steelblue', alpha=0.7) # Customize plot if 'predictor' in plot_df.columns: ax.set_yticks(range(len(plot_df))) ax.set_yticklabels(plot_df['predictor'], fontsize=10) ax.set_xlabel(column_name, fontsize=12) ax.set_title(f'{column_name} {title_suffix}', fontsize=14, fontweight='bold') # Add value labels for i, (bar, val) in enumerate(zip(bars, plot_df[column_name])): ax.text(bar.get_width() + 0.01 * max(plot_df[column_name]), bar.get_y() + bar.get_height()/2, f'{val:.3f}', va='center', fontsize=9) ax.grid(axis='x', alpha=0.3) plt.tight_layout() return fig def process_file_and_plot(file, plot_type, column_or_metric): """Main function to process file and create plots""" if file is None: return None, "Please upload a CSV file first" try: df = pd.read_csv(file) if plot_type == "Bar Plot": if column_or_metric not in df.columns: available_cols = [col for col in ['AUC', 'AUC_cond', 'AUC_marg', 'AUC_cv_group', 'R2_marginal', 'R2_conditional', 'p_value'] if col in df.columns] return None, f"Column '{column_or_metric}' not found. Available columns: {available_cols}" fig = create_bar_plot(df, column_or_metric) return fig, f"Bar plot created for {column_or_metric}" except Exception as e: return None, f"Error processing file: {str(e)}" def update_dataframe_display(file, sort_col, ascending): """Update dataframe display with sorting""" if file is None: return None try: df = pd.read_csv(file) if sort_col and sort_col in df.columns: df = sort_dataframe(df, sort_col, ascending) # Round numeric columns to 3 decimal places numeric_cols = df.select_dtypes(include=[np.number]).columns df[numeric_cols] = df[numeric_cols].round(3) return df except: return None # Create Gradio interface with gr.Blocks(title="Statistical Results Visualizer", theme=gr.themes.Soft()) as demo: gr.Markdown(""" # 📊 Statistical Results Visualizer **⚠️ PRIVACY NOTICE: This application does NOT store or save your data. All processing is done temporarily in memory only.** Upload your CSV file with statistical results to create interactive visualizations: - **Bar Plots**: For AUC, R-square, p-values - **Interactive Table**: Sort and explore your data (all values rounded to 3 decimal places) - **🔒 Your data is processed locally and never saved to servers** """) with gr.Row(): with gr.Column(scale=1): file_upload = gr.File( label="Upload CSV File", file_types=[".csv"], type="filepath" ) gr.Markdown("### 🎨 Visualization Options") plot_type = gr.Radio( choices=["Bar Plot"], label="Plot Type", value="Bar Plot" ) column_metric = gr.Dropdown( choices=["AUC", "AUC_cond", "AUC_marg", "AUC_cv_group", "R2_marginal", "R2_conditional", "p_value"], label="Select Metric/Column", value="AUC" ) create_plot_btn = gr.Button("Create Plot", variant="primary") gr.Markdown("### 📋 Table Options") sort_column = gr.Dropdown( choices=[], label="Sort by Column", interactive=True ) ascending_sort = gr.Checkbox( label="Ascending Order", value=True ) with gr.Column(scale=2): plot_output = gr.Plot(label="Visualization") plot_status = gr.Textbox(label="Status", interactive=False) with gr.Row(): dataframe_output = gr.Dataframe( label="Data Table", interactive=False, wrap=True ) # Update dropdown choices when file is uploaded def update_dropdown_choices(file): if file is None: return gr.Dropdown(choices=[]) try: df = pd.read_csv(file) return gr.Dropdown(choices=list(df.columns)) except: return gr.Dropdown(choices=[]) # Event handlers file_upload.change( fn=update_dropdown_choices, inputs=[file_upload], outputs=[sort_column] ) file_upload.change( fn=update_dataframe_display, inputs=[file_upload, sort_column, ascending_sort], outputs=[dataframe_output] ) create_plot_btn.click( fn=process_file_and_plot, inputs=[file_upload, plot_type, column_metric], outputs=[plot_output, plot_status] ) sort_column.change( fn=update_dataframe_display, inputs=[file_upload, sort_column, ascending_sort], outputs=[dataframe_output] ) ascending_sort.change( fn=update_dataframe_display, inputs=[file_upload, sort_column, ascending_sort], outputs=[dataframe_output] ) if __name__ == "__main__": demo.launch()