Sajid030 commited on
Commit
03afb00
Β·
verified Β·
1 Parent(s): 21b62f7

Update src/app.py

Browse files
Files changed (1) hide show
  1. src/app.py +221 -222
src/app.py CHANGED
@@ -1,222 +1,221 @@
1
- import streamlit as st
2
- import numpy as np
3
- import pandas as pd
4
- from AutoVisualizer.processing import check_dataset_cleanliness, task_type,is_probably_categorical, is_discrete, is_continuous, parse_datetime_columns
5
- from AutoVisualizer.categorical_viz import combine_figures_as_subplots, generate_count_plots, generate_bar_plots, generate_grouped_bar_plots, generate_pie_plots, generate_categorical_correlation_heatmap
6
- from AutoVisualizer.numerical_viz import generate_box_plots, generate_numeric_correlation_heatmap, generate_scatter_plots, generate_histograms, generate_line_plots
7
-
8
- st.set_page_config(page_title= "Auto-Visualizer",page_icon= "πŸ“Š",layout="wide")
9
- # col1, col2 = st.columns([0.3, 0.7])
10
-
11
- with st.sidebar:
12
- # Upload the dataset file (can upload only CSV, XLSX, JSON, XML)
13
- uploaded_file = st.file_uploader("Upload your dataset file:", ["csv", "xlsx", "json", "xml"])
14
-
15
- if uploaded_file is not None:
16
- file_type = uploaded_file.name
17
-
18
- try:
19
- # Read the dataset through pandas
20
- if file_type.endswith(".csv"):
21
- df = pd.read_csv(uploaded_file)
22
- elif file_type.endswith(".xlsx"):
23
- df = pd.read_excel(uploaded_file)
24
- elif file_type.endswith(".json"):
25
- df = pd.read_json(uploaded_file)
26
- else:
27
- df = pd.read_xml(uploaded_file)
28
- except Exception as e:
29
- st.write("Error:", e)
30
-
31
- with st.sidebar:
32
- # Show a a Disclaimer to user to upload as clean data as possible
33
- st.info("""
34
- ⚠️ **Heads up!** For the best experience, please upload a clean dataset.
35
-
36
- This app is designed for *visualizing data*, not cleaning it.
37
-
38
- πŸ“Œ *Tip:* Use the quick checker below to spot potential issues.
39
- """)
40
-
41
- if st.button("Run Cleanliness Check"):
42
- # Use session state to track button click
43
- st.session_state.run_clean_check = True
44
- st.divider()
45
-
46
- # Display the cleanliness checker result on the main page (not sidebar) if button was clicked
47
- if st.session_state.get("run_clean_check", False):
48
- with st.expander("➑️ See Cleanliness Checker Result"):
49
- check_dataset_cleanliness(df)
50
-
51
- # Display the user DataFrame
52
- st.markdown("Your Dataset:")
53
- st.dataframe(df, height=210)
54
- st.divider()
55
-
56
- # Extract column names from the dataset + add "No Target" element if there's no target in the user dataset
57
- feature_list = list(df.columns)
58
- target_selector = ["No Target"] + feature_list
59
-
60
- with st.sidebar:
61
- # Ask the user to select target column from their dataset
62
- target_col = st.selectbox("Specify the target column in your dataset:", target_selector)
63
- # Identify the task/type of dataset (i.e. classification/regression/clustering(if no target feature at all))
64
- task = task_type(df, target_col)
65
- # Display the task to user
66
- st.write(f"πŸ” Task identified: **{task}**")
67
-
68
- # Identify the date-time columns (if any) and extract new time-based components from it
69
- # date_time_ls --> List that will store date-time feature names
70
- # extracted_datetime --> List that will store extracted date-time feature names
71
- df, date_time_ls, extracted_datetime = parse_datetime_columns(df)
72
-
73
- # Remove date-time feature names as we already extracted time based components from it
74
- feature_list = [x for x in feature_list if x not in date_time_ls]
75
-
76
- categorical_ls = [] # List that will store categorical feature names
77
- discrete_ls = [] # List that will store discrete feature names
78
- continuous_ls = [] # List that will store continuous feature names
79
- for feature in feature_list:
80
- if is_probably_categorical(df[feature]):
81
- categorical_ls.append(feature) # Calling Categorical Feature Identifier Function
82
- elif is_discrete(df[feature]):
83
- discrete_ls.append(feature) # Calling Discrete Feature Identifier Function
84
- elif is_continuous(df[feature]):
85
- continuous_ls.append(feature) # Calling Continuous Feature Identifier Function
86
- # Add time based components that appear to be categorical
87
- for feature in extracted_datetime:
88
- if is_probably_categorical(df[feature]):
89
- categorical_ls.append(feature)
90
-
91
- # Creating Dialog Box to show identified features
92
- @st.dialog("Identified/Extracted Features from your Dataset:-")
93
- def open_dialog():
94
- if categorical_ls:
95
- with st.popover("Categorical Features", use_container_width= True):
96
- st.code("\n".join([f"β€’ {item}" for item in categorical_ls]))
97
- if discrete_ls:
98
- with st.popover("Discrete Features", use_container_width= True):
99
- st.code("\n".join([f"β€’ {item}" for item in discrete_ls]))
100
- if continuous_ls:
101
- with st.popover("Continuous Features", use_container_width= True):
102
- st.code("\n".join([f"β€’ {item}" for item in continuous_ls]))
103
- if date_time_ls:
104
- with st.popover("Date-Time Features", use_container_width= True):
105
- st.code("\n".join([f"β€’ {item}" for item in date_time_ls]))
106
- with st.popover("Extracted features from your Date-Time like features", use_container_width= True):
107
- st.code("\n".join([f"β€’ {item}" for item in extracted_datetime]))
108
- with st.sidebar:
109
- # Calling the dialog box through a button
110
- if st.button("See Your Feature Details"):
111
- open_dialog()
112
-
113
- # Generate the Plots
114
- with st.spinner("Generating Plots.....", show_time= True):
115
- if categorical_ls:
116
- st.header("πŸ“Š Categorical Plots")
117
- # 1. Count Plots
118
- count_plots = []
119
- for x_col in categorical_ls:
120
- if df[x_col].nunique() <= 20:
121
- count_plots.extend(generate_count_plots(df, x_col))
122
-
123
- if count_plots:
124
- st.subheader("Count Plots :-")
125
- st.plotly_chart(combine_figures_as_subplots(count_plots), use_container_width=True)
126
-
127
- # 2. Bar Plots
128
- bar_plots = []
129
- # (Categorical vs Discrete + Continuous)
130
- for x_col in categorical_ls:
131
- if df[x_col].nunique() <= 20:
132
- bar_plots.extend(generate_bar_plots(df, x_col, discrete_ls + continuous_ls))
133
-
134
- if bar_plots:
135
- st.subheader("Bar Plots :-")
136
- st.plotly_chart(combine_figures_as_subplots(bar_plots), use_container_width=True)
137
-
138
- # 3. Grouped Bar Plots
139
- grp_bar_plots = []
140
- # (Categorical vs Discrete + Continuous)
141
- grp_bar_plots.extend(generate_grouped_bar_plots(df, categorical_ls, discrete_ls + continuous_ls))
142
-
143
- if grp_bar_plots:
144
- st.subheader("Grouped Bar Plots :-")
145
- st.plotly_chart(combine_figures_as_subplots(grp_bar_plots), use_container_width=True)
146
-
147
- # 4. Pie Charts
148
- pie_plots = []
149
- for x_col in categorical_ls:
150
- if df[x_col].nunique() <= 20:
151
- pie_plots.extend(generate_pie_plots(df, x_col))
152
-
153
- if pie_plots:
154
- st.subheader("Pie Charts :-")
155
- st.plotly_chart(combine_figures_as_subplots(pie_plots), use_container_width=True)
156
-
157
- if continuous_ls:
158
- st.header("πŸ“Š Numerical Plots")
159
- # 5. Box Plots
160
- box_plots = []
161
- for x_col in categorical_ls:
162
- if df[x_col].nunique() <= 10:
163
- box_plots.extend(generate_box_plots(df, x_col, continuous_ls))
164
-
165
- if box_plots:
166
- st.subheader("Box Plots :-")
167
- st.plotly_chart(combine_figures_as_subplots(box_plots), use_container_width=True)
168
-
169
- # 6. Heat Maps
170
- heat_maps = []
171
- if task == 'Regression':
172
- if categorical_ls:
173
- heat_maps.extend(generate_categorical_correlation_heatmap(df, target_col, categorical_ls))
174
- heat_maps.extend(generate_numeric_correlation_heatmap(df[continuous_ls]))
175
- if heat_maps:
176
- st.subheader("Heat Maps :-")
177
- st.plotly_chart(combine_figures_as_subplots(heat_maps), use_container_width=True)
178
-
179
- # 7. Scatter Plots
180
- if len(continuous_ls) >= 2:
181
- st.subheader("Scatter Plots")
182
- scatter_plots = []
183
- # Creation of unique feature pairs (no repetition like (B, A) if (A, B) is already used)
184
- feature_pairs = []
185
- for i in range(len(continuous_ls)):
186
- for j in range(i + 1, len(continuous_ls)):
187
- feature_pairs.append((continuous_ls[i], continuous_ls[j]))
188
- selection = st.pills("Highlight using a categorical feature :- ", categorical_ls)
189
- scatter_plots.extend(generate_scatter_plots(df, feature_pairs, selection))
190
- if scatter_plots:
191
- st.plotly_chart(combine_figures_as_subplots(scatter_plots), use_container_width=True)
192
-
193
- # 8. Histograms
194
- histograms = []
195
- histograms.extend(generate_histograms(df, continuous_ls))
196
-
197
- if histograms:
198
- st.subheader("Histograms")
199
- st.plotly_chart(combine_figures_as_subplots(histograms), use_container_width=True)
200
-
201
- # 9. Line Plots
202
- line_plots = []
203
- if date_time_ls:
204
- # Extract only date-related components
205
- date_related_keywords = ['_year', '_month', '_day', '_weekday']
206
- date_component_cols = [col for col in extracted_datetime if any(key in col for key in date_related_keywords)]
207
- if date_component_cols:
208
- st.subheader("Line Plots :-")
209
- # Mapping of labels to values
210
- time_grouping_options = {
211
- "Daily": "D",
212
- "Weekly": "W",
213
- "Monthly": "ME",
214
- "Yearly": "YE"
215
- }
216
- time_choice = st.pills("Choose time interval for grouping :- ", list(time_grouping_options.keys()))
217
- # Extract the actual value for resampling
218
- selected_freq = time_grouping_options[time_choice] if time_choice else "ME" # Use default "ME" if no selection
219
- line_plots.extend(generate_line_plots(df, date_component_cols, continuous_ls, selected_freq))
220
-
221
- if line_plots:
222
- st.plotly_chart(combine_figures_as_subplots(line_plots), use_container_width= True)
 
1
+ import streamlit as st
2
+ import numpy as np
3
+ import pandas as pd
4
+ from AutoVisualizer.processing import check_dataset_cleanliness, task_type,is_probably_categorical, is_discrete, is_continuous, parse_datetime_columns
5
+ from AutoVisualizer.categorical_viz import combine_figures_as_subplots, generate_count_plots, generate_bar_plots, generate_grouped_bar_plots, generate_pie_plots, generate_categorical_correlation_heatmap
6
+ from AutoVisualizer.numerical_viz import generate_box_plots, generate_numeric_correlation_heatmap, generate_scatter_plots, generate_histograms, generate_line_plots
7
+
8
+ # st.set_page_config(page_title= "Auto-Visualizer",page_icon= "πŸ“Š",layout="wide")
9
+
10
+ with st.sidebar:
11
+ # Upload the dataset file (can upload only CSV, XLSX, JSON, XML)
12
+ uploaded_file = st.file_uploader("Upload your dataset file:", ["csv", "xlsx", "json", "xml"])
13
+
14
+ if uploaded_file is not None:
15
+ file_type = uploaded_file.name
16
+
17
+ try:
18
+ # Read the dataset through pandas
19
+ if file_type.endswith(".csv"):
20
+ df = pd.read_csv(uploaded_file)
21
+ elif file_type.endswith(".xlsx"):
22
+ df = pd.read_excel(uploaded_file)
23
+ elif file_type.endswith(".json"):
24
+ df = pd.read_json(uploaded_file)
25
+ else:
26
+ df = pd.read_xml(uploaded_file)
27
+ except Exception as e:
28
+ st.write("Error:", e)
29
+
30
+ with st.sidebar:
31
+ # Show a a Disclaimer to user to upload as clean data as possible
32
+ st.info("""
33
+ ⚠️ **Heads up!** For the best experience, please upload a clean dataset.
34
+
35
+ This app is designed for *visualizing data*, not cleaning it.
36
+
37
+ πŸ“Œ *Tip:* Use the quick checker below to spot potential issues.
38
+ """)
39
+
40
+ if st.button("Run Cleanliness Check"):
41
+ # Use session state to track button click
42
+ st.session_state.run_clean_check = True
43
+ st.divider()
44
+
45
+ # Display the cleanliness checker result on the main page (not sidebar) if button was clicked
46
+ if st.session_state.get("run_clean_check", False):
47
+ with st.expander("➑️ See Cleanliness Checker Result"):
48
+ check_dataset_cleanliness(df)
49
+
50
+ # Display the user DataFrame
51
+ st.markdown("Your Dataset:")
52
+ st.dataframe(df, height=210)
53
+ st.divider()
54
+
55
+ # Extract column names from the dataset + add "No Target" element if there's no target in the user dataset
56
+ feature_list = list(df.columns)
57
+ target_selector = ["No Target"] + feature_list
58
+
59
+ with st.sidebar:
60
+ # Ask the user to select target column from their dataset
61
+ target_col = st.selectbox("Specify the target column in your dataset:", target_selector)
62
+ # Identify the task/type of dataset (i.e. classification/regression/clustering(if no target feature at all))
63
+ task = task_type(df, target_col)
64
+ # Display the task to user
65
+ st.write(f"πŸ” Task identified: **{task}**")
66
+
67
+ # Identify the date-time columns (if any) and extract new time-based components from it
68
+ # date_time_ls --> List that will store date-time feature names
69
+ # extracted_datetime --> List that will store extracted date-time feature names
70
+ df, date_time_ls, extracted_datetime = parse_datetime_columns(df)
71
+
72
+ # Remove date-time feature names as we already extracted time based components from it
73
+ feature_list = [x for x in feature_list if x not in date_time_ls]
74
+
75
+ categorical_ls = [] # List that will store categorical feature names
76
+ discrete_ls = [] # List that will store discrete feature names
77
+ continuous_ls = [] # List that will store continuous feature names
78
+ for feature in feature_list:
79
+ if is_probably_categorical(df[feature]):
80
+ categorical_ls.append(feature) # Calling Categorical Feature Identifier Function
81
+ elif is_discrete(df[feature]):
82
+ discrete_ls.append(feature) # Calling Discrete Feature Identifier Function
83
+ elif is_continuous(df[feature]):
84
+ continuous_ls.append(feature) # Calling Continuous Feature Identifier Function
85
+ # Add time based components that appear to be categorical
86
+ for feature in extracted_datetime:
87
+ if is_probably_categorical(df[feature]):
88
+ categorical_ls.append(feature)
89
+
90
+ # Creating Dialog Box to show identified features
91
+ @st.dialog("Identified/Extracted Features from your Dataset:-")
92
+ def open_dialog():
93
+ if categorical_ls:
94
+ with st.popover("Categorical Features", use_container_width= True):
95
+ st.code("\n".join([f"β€’ {item}" for item in categorical_ls]))
96
+ if discrete_ls:
97
+ with st.popover("Discrete Features", use_container_width= True):
98
+ st.code("\n".join([f"β€’ {item}" for item in discrete_ls]))
99
+ if continuous_ls:
100
+ with st.popover("Continuous Features", use_container_width= True):
101
+ st.code("\n".join([f"β€’ {item}" for item in continuous_ls]))
102
+ if date_time_ls:
103
+ with st.popover("Date-Time Features", use_container_width= True):
104
+ st.code("\n".join([f"β€’ {item}" for item in date_time_ls]))
105
+ with st.popover("Extracted features from your Date-Time like features", use_container_width= True):
106
+ st.code("\n".join([f"β€’ {item}" for item in extracted_datetime]))
107
+ with st.sidebar:
108
+ # Calling the dialog box through a button
109
+ if st.button("See Your Feature Details"):
110
+ open_dialog()
111
+
112
+ # Generate the Plots
113
+ with st.spinner("Generating Plots.....", show_time= True):
114
+ if categorical_ls:
115
+ st.header("πŸ“Š Categorical Plots")
116
+ # 1. Count Plots
117
+ count_plots = []
118
+ for x_col in categorical_ls:
119
+ if df[x_col].nunique() <= 20:
120
+ count_plots.extend(generate_count_plots(df, x_col))
121
+
122
+ if count_plots:
123
+ st.subheader("Count Plots :-")
124
+ st.plotly_chart(combine_figures_as_subplots(count_plots), use_container_width=True)
125
+
126
+ # 2. Bar Plots
127
+ bar_plots = []
128
+ # (Categorical vs Discrete + Continuous)
129
+ for x_col in categorical_ls:
130
+ if df[x_col].nunique() <= 20:
131
+ bar_plots.extend(generate_bar_plots(df, x_col, discrete_ls + continuous_ls))
132
+
133
+ if bar_plots:
134
+ st.subheader("Bar Plots :-")
135
+ st.plotly_chart(combine_figures_as_subplots(bar_plots), use_container_width=True)
136
+
137
+ # 3. Grouped Bar Plots
138
+ grp_bar_plots = []
139
+ # (Categorical vs Discrete + Continuous)
140
+ grp_bar_plots.extend(generate_grouped_bar_plots(df, categorical_ls, discrete_ls + continuous_ls))
141
+
142
+ if grp_bar_plots:
143
+ st.subheader("Grouped Bar Plots :-")
144
+ st.plotly_chart(combine_figures_as_subplots(grp_bar_plots), use_container_width=True)
145
+
146
+ # 4. Pie Charts
147
+ pie_plots = []
148
+ for x_col in categorical_ls:
149
+ if df[x_col].nunique() <= 20:
150
+ pie_plots.extend(generate_pie_plots(df, x_col))
151
+
152
+ if pie_plots:
153
+ st.subheader("Pie Charts :-")
154
+ st.plotly_chart(combine_figures_as_subplots(pie_plots), use_container_width=True)
155
+
156
+ if continuous_ls:
157
+ st.header("πŸ“Š Numerical Plots")
158
+ # 5. Box Plots
159
+ box_plots = []
160
+ for x_col in categorical_ls:
161
+ if df[x_col].nunique() <= 10:
162
+ box_plots.extend(generate_box_plots(df, x_col, continuous_ls))
163
+
164
+ if box_plots:
165
+ st.subheader("Box Plots :-")
166
+ st.plotly_chart(combine_figures_as_subplots(box_plots), use_container_width=True)
167
+
168
+ # 6. Heat Maps
169
+ heat_maps = []
170
+ if task == 'Regression':
171
+ if categorical_ls:
172
+ heat_maps.extend(generate_categorical_correlation_heatmap(df, target_col, categorical_ls))
173
+ heat_maps.extend(generate_numeric_correlation_heatmap(df[continuous_ls]))
174
+ if heat_maps:
175
+ st.subheader("Heat Maps :-")
176
+ st.plotly_chart(combine_figures_as_subplots(heat_maps), use_container_width=True)
177
+
178
+ # 7. Scatter Plots
179
+ if len(continuous_ls) >= 2:
180
+ st.subheader("Scatter Plots")
181
+ scatter_plots = []
182
+ # Creation of unique feature pairs (no repetition like (B, A) if (A, B) is already used)
183
+ feature_pairs = []
184
+ for i in range(len(continuous_ls)):
185
+ for j in range(i + 1, len(continuous_ls)):
186
+ feature_pairs.append((continuous_ls[i], continuous_ls[j]))
187
+ selection = st.pills("Highlight using a categorical feature :- ", categorical_ls)
188
+ scatter_plots.extend(generate_scatter_plots(df, feature_pairs, selection))
189
+ if scatter_plots:
190
+ st.plotly_chart(combine_figures_as_subplots(scatter_plots), use_container_width=True)
191
+
192
+ # 8. Histograms
193
+ histograms = []
194
+ histograms.extend(generate_histograms(df, continuous_ls))
195
+
196
+ if histograms:
197
+ st.subheader("Histograms")
198
+ st.plotly_chart(combine_figures_as_subplots(histograms), use_container_width=True)
199
+
200
+ # 9. Line Plots
201
+ line_plots = []
202
+ if date_time_ls:
203
+ # Extract only date-related components
204
+ date_related_keywords = ['_year', '_month', '_day', '_weekday']
205
+ date_component_cols = [col for col in extracted_datetime if any(key in col for key in date_related_keywords)]
206
+ if date_component_cols:
207
+ st.subheader("Line Plots :-")
208
+ # Mapping of labels to values
209
+ time_grouping_options = {
210
+ "Daily": "D",
211
+ "Weekly": "W",
212
+ "Monthly": "ME",
213
+ "Yearly": "YE"
214
+ }
215
+ time_choice = st.pills("Choose time interval for grouping :- ", list(time_grouping_options.keys()))
216
+ # Extract the actual value for resampling
217
+ selected_freq = time_grouping_options[time_choice] if time_choice else "ME" # Use default "ME" if no selection
218
+ line_plots.extend(generate_line_plots(df, date_component_cols, continuous_ls, selected_freq))
219
+
220
+ if line_plots:
221
+ st.plotly_chart(combine_figures_as_subplots(line_plots), use_container_width= True)