Sajid030 commited on
Commit
5663a2a
Β·
verified Β·
1 Parent(s): 703fecc

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +224 -222
app.py CHANGED
@@ -1,222 +1,224 @@
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
+ # 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
+ if st.button("Generate Plots"):
114
+ # Generate the Plots
115
+ with st.spinner("Generating Plots.....", show_time= True):
116
+ if categorical_ls:
117
+ st.header("πŸ“Š Categorical Plots")
118
+ # 1. Count Plots
119
+ count_plots = []
120
+ for x_col in categorical_ls:
121
+ if df[x_col].nunique() <= 20:
122
+ count_plots.extend(generate_count_plots(df, x_col))
123
+
124
+ if count_plots:
125
+ st.subheader("Count Plots :-")
126
+ st.plotly_chart(combine_figures_as_subplots(count_plots), use_container_width=True)
127
+
128
+ # 2. Bar Plots
129
+ bar_plots = []
130
+ # (Categorical vs Discrete + Continuous)
131
+ for x_col in categorical_ls:
132
+ if df[x_col].nunique() <= 20:
133
+ bar_plots.extend(generate_bar_plots(df, x_col, discrete_ls + continuous_ls))
134
+
135
+ if bar_plots:
136
+ st.subheader("Bar Plots :-")
137
+ st.plotly_chart(combine_figures_as_subplots(bar_plots), use_container_width=True)
138
+
139
+ # 3. Grouped Bar Plots
140
+ grp_bar_plots = []
141
+ # (Categorical vs Discrete + Continuous)
142
+ grp_bar_plots.extend(generate_grouped_bar_plots(df, categorical_ls, discrete_ls + continuous_ls))
143
+
144
+ if grp_bar_plots:
145
+ st.subheader("Grouped Bar Plots :-")
146
+ st.plotly_chart(combine_figures_as_subplots(grp_bar_plots), use_container_width=True)
147
+
148
+ # 4. Pie Charts
149
+ pie_plots = []
150
+ for x_col in categorical_ls:
151
+ if df[x_col].nunique() <= 20:
152
+ pie_plots.extend(generate_pie_plots(df, x_col))
153
+
154
+ if pie_plots:
155
+ st.subheader("Pie Charts :-")
156
+ st.plotly_chart(combine_figures_as_subplots(pie_plots), use_container_width=True)
157
+
158
+ if continuous_ls:
159
+ st.header("πŸ“Š Numerical Plots")
160
+ # 5. Box Plots
161
+ box_plots = []
162
+ for x_col in categorical_ls:
163
+ if df[x_col].nunique() <= 10:
164
+ box_plots.extend(generate_box_plots(df, x_col, continuous_ls))
165
+
166
+ if box_plots:
167
+ st.subheader("Box Plots :-")
168
+ st.plotly_chart(combine_figures_as_subplots(box_plots), use_container_width=True)
169
+
170
+ # 6. Heat Maps
171
+ heat_maps = []
172
+ if task == 'Regression':
173
+ if categorical_ls:
174
+ heat_maps.extend(generate_categorical_correlation_heatmap(df, target_col, categorical_ls))
175
+ heat_maps.extend(generate_numeric_correlation_heatmap(df[continuous_ls]))
176
+ if heat_maps:
177
+ st.subheader("Heat Maps :-")
178
+ st.plotly_chart(combine_figures_as_subplots(heat_maps), use_container_width=True)
179
+
180
+ # 7. Scatter Plots
181
+ if len(continuous_ls) >= 2:
182
+ st.subheader("Scatter Plots")
183
+ scatter_plots = []
184
+ # Creation of unique feature pairs (no repetition like (B, A) if (A, B) is already used)
185
+ feature_pairs = []
186
+ for i in range(len(continuous_ls)):
187
+ for j in range(i + 1, len(continuous_ls)):
188
+ feature_pairs.append((continuous_ls[i], continuous_ls[j]))
189
+ selection = st.pills("Highlight using a categorical feature :- ", categorical_ls)
190
+ scatter_plots.extend(generate_scatter_plots(df, feature_pairs, selection))
191
+ if scatter_plots:
192
+ st.plotly_chart(combine_figures_as_subplots(scatter_plots), use_container_width=True)
193
+
194
+ # 8. Histograms
195
+ histograms = []
196
+ histograms.extend(generate_histograms(df, continuous_ls))
197
+
198
+ if histograms:
199
+ st.subheader("Histograms")
200
+ st.plotly_chart(combine_figures_as_subplots(histograms), use_container_width=True)
201
+
202
+ # 9. Line Plots
203
+ line_plots = []
204
+ if date_time_ls:
205
+ # Extract only date-related components
206
+ date_related_keywords = ['_year', '_month', '_day', '_weekday']
207
+ date_component_cols = [col for col in extracted_datetime if any(key in col for key in date_related_keywords)]
208
+ if date_component_cols:
209
+ st.subheader("Line Plots :-")
210
+ # Mapping of labels to values
211
+ time_grouping_options = {
212
+ "Daily": "D",
213
+ "Weekly": "W",
214
+ "Monthly": "ME",
215
+ "Yearly": "YE"
216
+ }
217
+ time_choice = st.pills("Choose time interval for grouping :- ", list(time_grouping_options.keys()))
218
+ # Extract the actual value for resampling
219
+ selected_freq = time_grouping_options[time_choice] if time_choice else "ME" # Use default "ME" if no selection
220
+ line_plots.extend(generate_line_plots(df, date_component_cols, continuous_ls, selected_freq))
221
+
222
+ if line_plots:
223
+ st.plotly_chart(combine_figures_as_subplots(line_plots), use_container_width= True)
224
+