hkayabilisim commited on
Commit
38308d3
·
1 Parent(s): 7ca9c4d

ui: added metric statistics (boxplot,table,etc)

Browse files

Right below the impact metrics gadgets, a new widget is added to display
the variation in the metrics via boxplot. All impact metric due to
different realizations are also diplayed as table as well as simple
statistics.

Files changed (1) hide show
  1. tomorrowcities/pages/engine.py +76 -1
tomorrowcities/pages/engine.py CHANGED
@@ -275,6 +275,7 @@ def create_new_app_state():
275
  'map_info_detail': solara.reactive({}),
276
  'tally_filter_cols': ['ds','income','material','gender','age','head','eduattstat','luf','occupancy'],
277
  'tally_is_available': solara.reactive(False),
 
278
  'metrics': {
279
  "metric1": {"desc": "Number of workers unemployed", "value": 0, "max_value": 100},
280
  "metric2": {"desc": "Number of children with no access to education", "value": 0, "max_value": 100},
@@ -1114,7 +1115,68 @@ def MetricPanel():
1114
  metric['max_value'],
1115
  layers.value['render_count'].value)
1116
 
1117
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1118
  @solara.component
1119
  def MapViewer():
1120
  print('rendering mapviewer')
@@ -1487,6 +1549,7 @@ def ExecutePanel():
1487
  else:
1488
  max_trials = 1
1489
 
 
1490
  for trial in range(1,max_trials+1):
1491
  if trial == 1:
1492
  set_progress_message('Running...')
@@ -1523,6 +1586,13 @@ def ExecutePanel():
1523
  store_info_to_session()
1524
  layers.value['tally_is_available'].value = True
1525
  tally_counter.value += 1
 
 
 
 
 
 
 
1526
  set_progress_message('')
1527
  # trigger render event
1528
  layers.value['render_count'].set(layers.value['render_count'].value + 1)
@@ -2021,6 +2091,11 @@ def WebApp():
2021
  with solara.Row(justify="center"):
2022
  MetricPanel()
2023
  #LayerDisplayer()
 
 
 
 
 
2024
  solara.Details(
2025
  summary="Layer Details",
2026
  children=[LayerDisplayer()],
 
275
  'map_info_detail': solara.reactive({}),
276
  'tally_filter_cols': ['ds','income','material','gender','age','head','eduattstat','luf','occupancy'],
277
  'tally_is_available': solara.reactive(False),
278
+ 'metrics_realized': solara.reactive(None),
279
  'metrics': {
280
  "metric1": {"desc": "Number of workers unemployed", "value": 0, "max_value": 100},
281
  "metric2": {"desc": "Number of children with no access to education", "value": 0, "max_value": 100},
 
1115
  metric['max_value'],
1116
  layers.value['render_count'].value)
1117
 
1118
+ @solara.component
1119
+ def MetricStatistics():
1120
+ if layers.value['metrics_realized'].value is None:
1121
+ solara.Text('There is no metrics statistics data yet!')
1122
+ return
1123
+
1124
+ # list of metrics measurements
1125
+ metrics = layers.value['metrics_realized'].value
1126
+
1127
+ # get the metric names from the first measurement
1128
+ metric_names = metrics[0].keys()
1129
+
1130
+ metric_dict = {}
1131
+ for metric_name in metric_names:
1132
+ metric_values = [m[metric_name]['value'] for m in metrics]
1133
+ metric_dict[metric_name] = metric_values
1134
+ df = pd.DataFrame.from_dict(metric_dict)
1135
+ summary = df.describe()
1136
+
1137
+ data = []
1138
+ for metric_name in metric_names:
1139
+ value = [float(summary[metric_name][k]) for k in ['min','25%','50%','75%','max']]
1140
+ data.append({"name":metric_name, "value": value})
1141
+
1142
+ options = {
1143
+ "title": [{"text": 'Impact Metrics of Different Realizations', "left": 'center' },],
1144
+ "tooltip": {
1145
+ "trigger": 'item',
1146
+ "axisPointer": {
1147
+ "type": 'shadow'
1148
+ }
1149
+ },
1150
+ "xAxis": {
1151
+ "type": 'category',
1152
+ "data": ['metric1', 'metric2', 'metric3', 'metric4','metric5', 'metric6', 'metric7', 'metric8'],
1153
+ },
1154
+ "yAxis": {
1155
+ "type": 'value',
1156
+ "splitArea": {
1157
+ "show": True
1158
+ }
1159
+ },
1160
+ "series": [
1161
+ {
1162
+ "name": 'boxplot',
1163
+ "type": 'boxplot',
1164
+ "itemStyle": {
1165
+ "color": '#b8c5f2'
1166
+ },
1167
+ "data": data
1168
+ },
1169
+ ]
1170
+ }
1171
+ with solara.lab.Tabs():
1172
+ with solara.lab.Tab("Boxplot"):
1173
+ with solara.GridFixed(columns=1):
1174
+ solara.FigureEcharts(option=options, attributes={"style": "height:400%; width:100%"})
1175
+ with solara.lab.Tab("Data"):
1176
+ solara.DataFrame(df)
1177
+ with solara.lab.Tab("Stats"):
1178
+ solara.DataFrame(summary.reset_index())
1179
+
1180
  @solara.component
1181
  def MapViewer():
1182
  print('rendering mapviewer')
 
1549
  else:
1550
  max_trials = 1
1551
 
1552
+ metrics_results = []
1553
  for trial in range(1,max_trials+1):
1554
  if trial == 1:
1555
  set_progress_message('Running...')
 
1586
  store_info_to_session()
1587
  layers.value['tally_is_available'].value = True
1588
  tally_counter.value += 1
1589
+
1590
+ metrics_result = generate_metrics(tally_geo, tally_geo,
1591
+ layers.value['hazard'].value,
1592
+ population_displacement_consensus.value)
1593
+ metrics_results.append(metrics_result)
1594
+
1595
+ layers.value['metrics_realized'].set(metrics_results)
1596
  set_progress_message('')
1597
  # trigger render event
1598
  layers.value['render_count'].set(layers.value['render_count'].value + 1)
 
2091
  with solara.Row(justify="center"):
2092
  MetricPanel()
2093
  #LayerDisplayer()
2094
+ solara.Details(
2095
+ summary="Metric Statistics",
2096
+ children=[MetricStatistics()],
2097
+ expand=False
2098
+ )
2099
  solara.Details(
2100
  summary="Layer Details",
2101
  children=[LayerDisplayer()],