apple commited on
Commit
1771ae9
Β·
1 Parent(s): f756dca

Add Statistical Results Visualizer with privacy protection

Browse files
Files changed (3) hide show
  1. README.md +29 -12
  2. app.py +232 -0
  3. requirements.txt +5 -0
README.md CHANGED
@@ -1,12 +1,29 @@
1
- ---
2
- title: Statistical Visualizer
3
- emoji: πŸŒ–
4
- colorFrom: gray
5
- colorTo: purple
6
- sdk: gradio
7
- sdk_version: 5.44.1
8
- app_file: app.py
9
- pinned: false
10
- ---
11
-
12
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Statistical Results Visualizer
2
+
3
+ A secure Gradio application for visualizing statistical analysis results from CSV files.
4
+
5
+ ## πŸ”’ Privacy & Security
6
+ - **NO DATA STORAGE**: Your data is never saved or stored
7
+ - **TEMPORARY PROCESSING**: All data processing happens in memory only
8
+ - **NO LOGGING**: Upload history and data are not logged
9
+ - **SECURE**: Files are processed locally and discarded after use
10
+
11
+ ## Features
12
+ - Upload CSV files with statistical results
13
+ - Create bar plots for AUC, R-square, p-values
14
+ - Interactive table with sorting functionality
15
+ - All numeric values displayed with 3 decimal places
16
+
17
+ ## Usage
18
+ 1. Upload your CSV file (processed temporarily only)
19
+ 2. Select visualization type and metric
20
+ 3. Create plots and explore data in the interactive table
21
+ 4. Data is automatically discarded when session ends
22
+
23
+ ## Supported Metrics
24
+ - AUC (Area Under Curve)
25
+ - R-squared values
26
+ - p-values
27
+ - Various confidence intervals
28
+
29
+ Perfect for analyzing GLMM and LMM statistical results with complete data privacy!
app.py ADDED
@@ -0,0 +1,232 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import pandas as pd
3
+ import numpy as np
4
+ import matplotlib.pyplot as plt
5
+ import seaborn as sns
6
+ from matplotlib.patches import Rectangle
7
+ import io
8
+ import warnings
9
+ warnings.filterwarnings('ignore')
10
+
11
+ # Set style for better plots
12
+ plt.style.use('default')
13
+ sns.set_palette("husl")
14
+
15
+ def load_and_display_data(file):
16
+ """Load CSV file and return dataframe"""
17
+ if file is None:
18
+ return None, "Please upload a CSV file"
19
+
20
+ try:
21
+ df = pd.read_csv(file)
22
+ return df, f"Data loaded successfully! Shape: {df.shape}"
23
+ except Exception as e:
24
+ return None, f"Error loading file: {str(e)}"
25
+
26
+ def sort_dataframe(df, sort_column, ascending=True):
27
+ """Sort dataframe by selected column"""
28
+ if df is None or df.empty:
29
+ return df
30
+
31
+ if sort_column not in df.columns:
32
+ return df
33
+
34
+ try:
35
+ return df.sort_values(by=sort_column, ascending=ascending)
36
+ except:
37
+ return df
38
+
39
+ def create_bar_plot(df, column_name, title_suffix=""):
40
+ """Create bar plot for AUC, R-square, or p-values"""
41
+ if df is None or df.empty or column_name not in df.columns:
42
+ fig, ax = plt.subplots(figsize=(10, 6))
43
+ ax.text(0.5, 0.5, f'Column "{column_name}" not found in data',
44
+ ha='center', va='center', transform=ax.transAxes)
45
+ return fig
46
+
47
+ # Filter out missing values
48
+ plot_df = df[df[column_name].notna()].copy()
49
+
50
+ if plot_df.empty:
51
+ fig, ax = plt.subplots(figsize=(10, 6))
52
+ ax.text(0.5, 0.5, f'No valid data for "{column_name}"',
53
+ ha='center', va='center', transform=ax.transAxes)
54
+ return fig
55
+
56
+ # Group by predictor and take mean if multiple values
57
+ if 'predictor' in plot_df.columns:
58
+ plot_df = plot_df.groupby('predictor')[column_name].mean().reset_index()
59
+
60
+ # Sort by value
61
+ plot_df = plot_df.sort_values(column_name, ascending=True)
62
+
63
+ # Create plot
64
+ fig, ax = plt.subplots(figsize=(12, max(6, len(plot_df) * 0.3)))
65
+
66
+ bars = ax.barh(range(len(plot_df)), plot_df[column_name], color='steelblue', alpha=0.7)
67
+
68
+ # Customize plot
69
+ if 'predictor' in plot_df.columns:
70
+ ax.set_yticks(range(len(plot_df)))
71
+ ax.set_yticklabels(plot_df['predictor'], fontsize=10)
72
+
73
+ ax.set_xlabel(column_name, fontsize=12)
74
+ ax.set_title(f'{column_name} {title_suffix}', fontsize=14, fontweight='bold')
75
+
76
+ # Add value labels
77
+ for i, (bar, val) in enumerate(zip(bars, plot_df[column_name])):
78
+ ax.text(bar.get_width() + 0.01 * max(plot_df[column_name]),
79
+ bar.get_y() + bar.get_height()/2,
80
+ f'{val:.3f}', va='center', fontsize=9)
81
+
82
+ ax.grid(axis='x', alpha=0.3)
83
+ plt.tight_layout()
84
+
85
+ return fig
86
+
87
+
88
+ def process_file_and_plot(file, plot_type, column_or_metric):
89
+ """Main function to process file and create plots"""
90
+ if file is None:
91
+ return None, "Please upload a CSV file first"
92
+
93
+ try:
94
+ df = pd.read_csv(file)
95
+
96
+ if plot_type == "Bar Plot":
97
+ if column_or_metric not in df.columns:
98
+ available_cols = [col for col in ['AUC', 'AUC_cond', 'AUC_marg', 'AUC_cv_group',
99
+ 'R2_marginal', 'R2_conditional', 'p_value']
100
+ if col in df.columns]
101
+ return None, f"Column '{column_or_metric}' not found. Available columns: {available_cols}"
102
+
103
+ fig = create_bar_plot(df, column_or_metric)
104
+ return fig, f"Bar plot created for {column_or_metric}"
105
+
106
+ except Exception as e:
107
+ return None, f"Error processing file: {str(e)}"
108
+
109
+ def update_dataframe_display(file, sort_col, ascending):
110
+ """Update dataframe display with sorting"""
111
+ if file is None:
112
+ return None
113
+
114
+ try:
115
+ df = pd.read_csv(file)
116
+ if sort_col and sort_col in df.columns:
117
+ df = sort_dataframe(df, sort_col, ascending)
118
+
119
+ # Round numeric columns to 3 decimal places
120
+ numeric_cols = df.select_dtypes(include=[np.number]).columns
121
+ df[numeric_cols] = df[numeric_cols].round(3)
122
+
123
+ return df
124
+ except:
125
+ return None
126
+
127
+ # Create Gradio interface
128
+ with gr.Blocks(title="Statistical Results Visualizer", theme=gr.themes.Soft()) as demo:
129
+ gr.Markdown("""
130
+ # πŸ“Š Statistical Results Visualizer
131
+
132
+ **⚠️ PRIVACY NOTICE: This application does NOT store or save your data. All processing is done temporarily in memory only.**
133
+
134
+ Upload your CSV file with statistical results to create interactive visualizations:
135
+ - **Bar Plots**: For AUC, R-square, p-values
136
+ - **Interactive Table**: Sort and explore your data (all values rounded to 3 decimal places)
137
+ - **πŸ”’ Your data is processed locally and never saved to servers**
138
+ """)
139
+
140
+ with gr.Row():
141
+ with gr.Column(scale=1):
142
+ file_upload = gr.File(
143
+ label="Upload CSV File",
144
+ file_types=[".csv"],
145
+ type="filepath"
146
+ )
147
+
148
+ gr.Markdown("### 🎨 Visualization Options")
149
+
150
+ plot_type = gr.Radio(
151
+ choices=["Bar Plot"],
152
+ label="Plot Type",
153
+ value="Bar Plot"
154
+ )
155
+
156
+ column_metric = gr.Dropdown(
157
+ choices=["AUC", "AUC_cond", "AUC_marg", "AUC_cv_group",
158
+ "R2_marginal", "R2_conditional", "p_value"],
159
+ label="Select Metric/Column",
160
+ value="AUC"
161
+ )
162
+
163
+ create_plot_btn = gr.Button("Create Plot", variant="primary")
164
+
165
+ gr.Markdown("### πŸ“‹ Table Options")
166
+
167
+ sort_column = gr.Dropdown(
168
+ choices=[],
169
+ label="Sort by Column",
170
+ interactive=True
171
+ )
172
+
173
+ ascending_sort = gr.Checkbox(
174
+ label="Ascending Order",
175
+ value=True
176
+ )
177
+
178
+ with gr.Column(scale=2):
179
+ plot_output = gr.Plot(label="Visualization")
180
+ plot_status = gr.Textbox(label="Status", interactive=False)
181
+
182
+ with gr.Row():
183
+ dataframe_output = gr.Dataframe(
184
+ label="Data Table",
185
+ interactive=False,
186
+ wrap=True
187
+ )
188
+
189
+ # Update dropdown choices when file is uploaded
190
+ def update_dropdown_choices(file):
191
+ if file is None:
192
+ return gr.Dropdown(choices=[])
193
+
194
+ try:
195
+ df = pd.read_csv(file)
196
+ return gr.Dropdown(choices=list(df.columns))
197
+ except:
198
+ return gr.Dropdown(choices=[])
199
+
200
+ # Event handlers
201
+ file_upload.change(
202
+ fn=update_dropdown_choices,
203
+ inputs=[file_upload],
204
+ outputs=[sort_column]
205
+ )
206
+
207
+ file_upload.change(
208
+ fn=update_dataframe_display,
209
+ inputs=[file_upload, sort_column, ascending_sort],
210
+ outputs=[dataframe_output]
211
+ )
212
+
213
+ create_plot_btn.click(
214
+ fn=process_file_and_plot,
215
+ inputs=[file_upload, plot_type, column_metric],
216
+ outputs=[plot_output, plot_status]
217
+ )
218
+
219
+ sort_column.change(
220
+ fn=update_dataframe_display,
221
+ inputs=[file_upload, sort_column, ascending_sort],
222
+ outputs=[dataframe_output]
223
+ )
224
+
225
+ ascending_sort.change(
226
+ fn=update_dataframe_display,
227
+ inputs=[file_upload, sort_column, ascending_sort],
228
+ outputs=[dataframe_output]
229
+ )
230
+
231
+ if __name__ == "__main__":
232
+ demo.launch(share=True, server_name="0.0.0.0")
requirements.txt ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ gradio==5.44.1
2
+ matplotlib
3
+ seaborn
4
+ pandas
5
+ numpy