Skip to content

Commit 3fd8d51

Browse files
apayaniGitHub Enterprise
authored andcommitted
Merge pull request #83 from apayani/cleanup
Demo for image training, updates on dashboard, bug fixes
2 parents faab77c + 8625d09 commit 3fd8d51

File tree

138 files changed

+2544
-5114
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

138 files changed

+2544
-5114
lines changed

Dashboard/analysis_page.py

Lines changed: 29 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,10 @@
11
import logging
2-
import dash_bootstrap_components as dbc
3-
from dash import html, dcc
2+
from dash import dcc
43
import dash
54
from server import app, redisUtil
65
import metric_view_functions as mvf
76
from dash import Input, Output, html, State
8-
import dash_daq as daq
9-
import numpy as np
10-
import plotly.express as px
11-
import pandas as pd
7+
from dash.exceptions import PreventUpdate
128

139
logger = logging.getLogger(__name__)
1410

@@ -20,7 +16,7 @@ def get_analysis_page():
2016
html.H4("Select The Analysis"),
2117
dcc.Interval(
2218
id='analysis-interval-component',
23-
interval=1 * 1000, # in milliseconds
19+
interval=1 * 1500, # in milliseconds
2420
n_intervals=0),
2521
dcc.Dropdown(
2622
id="analysis_selector",
@@ -44,20 +40,36 @@ def get_analysis_page():
4440
)
4541
def get_analysis_updates(timer, btn, analysis_choice, analysis_choices, analysis_display):
4642
ctx = dash.callback_context
47-
is_time_update, is_button, is_value = mvf.analysis_update_cause(ctx, "analysis-")
48-
analysis_choices = redisUtil.get_available_analysis()
49-
if is_time_update:
50-
if redisUtil.has_update("analysis_update", reset=True):
51-
print("updating analysis data")
52-
analysis_display = [html.P(redisUtil.get_analysis(analysis_choice))]
53-
redisUtil._subscribers["analysis_update"] = False
43+
is_time_update = any('analysis-interval-component.n_intervals' in i['prop_id'] for i in ctx.triggered)
44+
is_button = any('run_analysis_button.n_clicks' in i['prop_id'] for i in ctx.triggered)
45+
is_value = any('analysis_selector.value' == i['prop_id'] for i in ctx.triggered)
46+
should_update = False
47+
48+
if analysis_choices != redisUtil.get_available_analysis():
49+
analysis_choices = redisUtil.get_available_analysis()
50+
should_update = True
51+
if is_time_update and analysis_choice is not None:
52+
if redisUtil.has_analysis_update(analysis_choice, reset=True):
53+
print("Analysis update: ")
54+
analysis_display = [redisUtil.get_analysis(analysis_choice),
55+
html.P(analysis_choice, style={"display": "none"})]
56+
return analysis_choices, analysis_display
5457
if is_button:
5558
if analysis_choice is None or analysis_choice == "":
5659
return analysis_choices, [html.P("Please select an analysis")]
5760
else:
5861
redisUtil.request_start_analysis(analysis_choice)
59-
return redisUtil.get_available_analysis(), [html.P("Starting analysis")]
60-
if is_value:
61-
analysis_display = [redisUtil.get_analysis(analysis_choice)]
62+
return redisUtil.get_available_analysis(), [html.P("Requesting Analysis..")]
63+
64+
# Extra condition was added because dash would not always update when changing to/from a large analysis
65+
if is_value or (len(analysis_display) > 1 and analysis_choice !=
66+
analysis_display[1].get("props", {}).get("children", {})):
67+
analysis_display = [redisUtil.get_analysis(analysis_choice),
68+
html.P(analysis_choice, style={"display": "none"})]
69+
should_update = True
70+
71+
if not should_update:
72+
raise PreventUpdate
73+
6274
return analysis_choices, analysis_display
6375

Dashboard/certificate_page.py

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -30,21 +30,22 @@ def get_cert_name(cert_id):
3030

3131
def generate_cert_table(id, show_explanation=True):
3232
rows = []
33-
for k, v in redisUtil.get_certificate_values()[id].items():
34-
if v['value']:
35-
status = html.Div([
36-
"Passed ", html.I(className="fa-solid fa-check",
37-
style={"width": "30px", "height": "30px", "margin-left": "10px", "color": "green"})
38-
])
39-
else:
40-
status = html.Div([
41-
"Failed", html.I(className="fa-solid fa-xmark",
42-
style={"width": "30px", "height": "30px", "margin-left": "25px", "color": "red"})
43-
])
44-
rows.append(html.Tr(
45-
[html.Td(get_cert_name(k)), html.Td(v['explanation']), html.Td(status)] if show_explanation else
46-
[html.Td(get_cert_name(k)), html.Td(status)]
47-
))
33+
if len(redisUtil.get_certificate_values()) > 0:
34+
for k, v in redisUtil.get_certificate_values()[id].items():
35+
if v['value']:
36+
status = html.Div([
37+
"Passed ", html.I(className="fa-solid fa-check",
38+
style={"width": "30px", "height": "30px", "margin-left": "10px", "color": "green"})
39+
])
40+
else:
41+
status = html.Div([
42+
"Failed", html.I(className="fa-solid fa-xmark",
43+
style={"width": "30px", "height": "30px", "margin-left": "25px", "color": "red"})
44+
])
45+
rows.append(html.Tr(
46+
[html.Td(get_cert_name(k)), html.Td(v['explanation']), html.Td(status)] if show_explanation else
47+
[html.Td(get_cert_name(k)), html.Td(status)]
48+
))
4849
return dbc.Table(
4950
children=[
5051
html.Thead(

Dashboard/data_summary_page.py

Lines changed: 76 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -1,92 +1,90 @@
11
import logging
2-
import dash_bootstrap_components as dbc
3-
from dash import html, dcc
4-
from server import redisUtil
5-
import dash_daq as daq
6-
import numpy as np
7-
import plotly.express as px
8-
import pandas as pd
2+
from dash import dcc
3+
import dash
4+
from server import app, redisUtil
5+
from dash import Input, Output, html, State
6+
from dash.exceptions import PreventUpdate
97

108
logger = logging.getLogger(__name__)
9+
INTERPRETATION_ANALYSIS = ["DataVisualization"]
10+
prefix = "data_"
1111

12-
def get_data_summary_page():
13-
return html.Div([
14-
html.H4(children='Data Summary'),
15-
get_summary()
16-
])
12+
13+
def get_available_options(options):
14+
result = [option for option in options if option in INTERPRETATION_ANALYSIS]
15+
return result
1716

1817

19-
def get_label_str(labels, label_name_dict):
20-
if label_name_dict == None or label_name_dict == "":
21-
labels_str = ",".join(str(i) for i in labels)
22-
else:
23-
label_str = ""
24-
for i, label in enumerate(label_name_dict):
25-
label_str += f"{label}({label_name_dict[label]})"
26-
if i < len(label_name_dict) - 1:
27-
label_str += ", "
28-
return label_str
18+
def get_data_summary_page():
19+
redisUtil.request_available_analysis()
20+
options = redisUtil.get_available_analysis()
21+
options = get_available_options(options)
22+
choice = options[0] if (options is not None and len(options) > 0) else None
23+
result = html.Div([
24+
html.H4("Run analysis"),
25+
dcc.Interval(
26+
id=prefix + 'interval-component',
27+
interval=1 * 3000, # in milliseconds
28+
n_intervals=0),
29+
dcc.Dropdown(
30+
id=prefix + "analysis_selector",
31+
options=options,
32+
value=choice,
33+
persistence=True),
34+
html.Button("Run Analysis", id=prefix + "run_analysis_button", style={"margin-top": "20px"}),
35+
html.Div([], id=prefix + "analysis_display", style={"margin-top": "20px"})
36+
], style={})
37+
return result
2938

3039

31-
def get_summary():
32-
data_summary = redisUtil.get_data_summary()
40+
@app.callback(
41+
Output(prefix + 'analysis_selector', 'options'),
42+
Output(prefix + 'analysis_display', 'children'),
43+
Output(prefix + 'analysis_selector', 'value'),
44+
Input(prefix + 'interval-component', 'n_intervals'),
45+
Input(prefix + 'run_analysis_button', 'n_clicks'),
46+
Input(prefix + 'analysis_selector', 'value'),
47+
State(prefix + 'analysis_selector', 'options'),
48+
State(prefix + 'analysis_display', 'children'),
49+
)
50+
def get_analysis_updates(timer, btn, analysis_choice, analysis_choices, analysis_display):
51+
ctx = dash.callback_context
52+
is_time_update = any(prefix + 'interval-component.n_intervals' in i['prop_id'] for i in ctx.triggered)
53+
is_button = any(prefix + 'run_analysis_button.n_clicks' in i['prop_id'] for i in ctx.triggered)
54+
is_value = any(prefix + 'analysis_selector.value' == i['prop_id'] for i in ctx.triggered)
55+
should_update = False
56+
force_new_display = False
3357

34-
label_name = data_summary["label_name"]
35-
target = data_summary["pred_target"]
36-
labels = data_summary["labels"]
58+
if analysis_choices != get_available_options(redisUtil.get_available_analysis()):
59+
analysis_choices = get_available_options(redisUtil.get_available_analysis())
60+
should_update = True
61+
if analysis_choice is None and (analysis_choices is not None and len(analysis_choices) > 0):
62+
analysis_choice = analysis_choices[0]
63+
force_new_display = True
3764

38-
label_str = get_label_str(labels, label_name)
39-
40-
train_label_dist = data_summary["label_dist"]["train"]
41-
test_label_dist = data_summary["label_dist"]["test"]
42-
train_label_df = pd.DataFrame({
43-
"label": train_label_dist.keys(),
44-
"freq": train_label_dist.values()
45-
})
46-
test_label_df = pd.DataFrame({
47-
"label": test_label_dist.keys(),
48-
"freq": test_label_dist.values()
49-
})
65+
if is_time_update and analysis_choice is not None:
66+
if redisUtil.has_analysis_update(analysis_choice, reset=True):
67+
print("Analysis update: ")
68+
analysis_display = [redisUtil.get_analysis(analysis_choice),
69+
html.P(analysis_choice, style={"display": "none"})]
70+
return analysis_choices, analysis_display
71+
if is_button:
72+
if analysis_choice is None or analysis_choice == "":
73+
return analysis_choices, [html.P("Please select an analysis")]
74+
else:
75+
redisUtil.request_start_analysis(analysis_choice)
76+
return redisUtil.get_available_analysis(), [html.P("Requesting Analysis..")]
5077

51-
train_hist = px.bar(train_label_df, x="label", y="freq", labels={})
52-
test_hist = px.bar(test_label_df, x="label", y="freq", labels={})
53-
train_hist.update_layout({"margin":{"l":0, "r":0, "t":0, "b":0}})
54-
train_hist.update_layout(xaxis={"visible": True, "showticklabels": True, "title": None}, yaxis={"visible": False, "showticklabels": False})
55-
test_hist.update_layout({"margin":{"l":0, "r":0, "t":0, "b":0}})
56-
test_hist.update_layout(xaxis={"visible": True, "showticklabels": True, "title": None}, yaxis={"visible": False, "showticklabels": False})
78+
# Extra condition was added because dash would not always update when changing to/from a large analysis
79+
if force_new_display or is_value or (analysis_choice and analysis_display==[]) \
80+
or ((len(analysis_display) > 1 and analysis_choice != analysis_display[1].get("props", {}).get("children", {}))):
81+
print("Value triggered")
82+
analysis_display = [redisUtil.get_analysis(analysis_choice),
83+
html.P(analysis_choice, style={"display": "none"})]
84+
should_update = True
5785

58-
row_target = html.Tr([
59-
html.Td("Target", className="data-summary-title"),
60-
html.Td(target, className="data-summary-content"),
61-
], className="data-summary-main-row")
62-
row_label = html.Tr([
63-
html.Td("Labels", className="data-summary-title"),
64-
html.Td(label_str, className="data-summary-content")
65-
], className="data-summary-main-row")
66-
67-
row_histogram = html.Tr([
68-
html.Td("Label Distribution", className="data-summary-title"),
69-
html.Td(get_histogram_cell(train_hist, test_hist))
70-
], className="data-summary-main-row")
86+
if not should_update:
87+
raise PreventUpdate
7188

72-
return dbc.Table(
73-
[row_target, row_label, row_histogram],
74-
striped=True,
75-
borderless=True,
76-
)
89+
return analysis_choices, analysis_display, analysis_choice
7790

78-
def get_histogram_cell(train_hist, test_hist):
79-
return dbc.Table([
80-
html.Tr([
81-
html.Td("Train Data", className="data-summary-content-hist-title"),
82-
html.Td("Test Data", className="data-summary-content-hist-title")
83-
]),
84-
html.Tr([
85-
html.Td([
86-
dcc.Graph(figure=train_hist, className="data-summary-content-hist", config={"responsive": True})
87-
], className="data-summary-content-half"),
88-
html.Td([
89-
dcc.Graph(figure=test_hist, className="data-summary-content-hist", config={"responsive": True})
90-
], className="data-summary-content-half")
91-
])
92-
], borderless=True, style={"margin": 0})

Dashboard/home_page.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,9 @@ def get_home_page():
4747
score_robust = []
4848
score_fair = []
4949
score_perform = []
50-
cert_values = redisUtil.get_certificate_values()[-1]
50+
cert_values = []
51+
if len(redisUtil.get_certificate_values()) > 0:
52+
cert_values = redisUtil.get_certificate_values()[-1]
5153

5254
for c in certs:
5355
for t in certs[c]["tags"]:

0 commit comments

Comments
 (0)