nataliaElv commited on
Commit
0c6044d
1 Parent(s): 884fd5e

Customize progress dashboard

Browse files
Files changed (1) hide show
  1. app.py +112 -280
app.py CHANGED
@@ -24,304 +24,127 @@ def get_progress(dataset: rg.Dataset) -> dict:
24
  "annotated": completed,
25
  "progress": progress,
26
  "users": {
27
- username: user_progress["completed"].get("submitted")
28
  for username, user_progress in dataset_progress["users"].items()
29
  }
30
  }
31
 
32
 
33
- def create_gauge_chart(progress):
34
- fig = go.Figure(
35
- go.Indicator(
36
- mode="gauge+number+delta",
37
- value=progress["progress"],
38
- title={"text": "Dataset Annotation Progress", "font": {"size": 24}},
39
- delta={"reference": 100, "increasing": {"color": "RebeccaPurple"}},
40
- number={"font": {"size": 40}, "valueformat": ".1f", "suffix": "%"},
41
- gauge={
42
- "axis": {"range": [None, 100], "tickwidth": 1, "tickcolor": "darkblue"},
43
- "bar": {"color": "deepskyblue"},
44
- "bgcolor": "white",
45
- "borderwidth": 2,
46
- "bordercolor": "gray",
47
- "steps": [
48
- {"range": [0, progress["progress"]], "color": "royalblue"},
49
- {"range": [progress["progress"], 100], "color": "lightgray"},
50
- ],
51
- "threshold": {
52
- "line": {"color": "red", "width": 4},
53
- "thickness": 0.75,
54
- "value": 100,
55
- },
56
- },
57
- )
58
- )
59
-
60
- fig.update_layout(
61
- annotations=[
62
- dict(
63
- text=(
64
- f"Total records: {progress['total']}<br>"
65
- f"Annotated: {progress['annotated']} ({progress['progress']:.1f}%)<br>"
66
- f"Remaining: {progress['total'] - progress['annotated']} ({100 - progress['progress']:.1f}%)"
67
- ),
68
- # x=0.5,
69
- # y=-0.2,
70
- showarrow=False,
71
- xref="paper",
72
- yref="paper",
73
- font=dict(size=16),
74
- )
75
- ],
76
- )
77
-
78
- fig.add_annotation(
79
- text=(
80
- f"Current Progress: {progress['progress']:.1f}% complete<br>"
81
- f"({progress['annotated']} out of {progress['total']} records annotated)"
82
- ),
83
- xref="paper",
84
- yref="paper",
85
- x=0.5,
86
- y=1.1,
87
- showarrow=False,
88
- font=dict(size=18),
89
- align="center",
90
- )
91
-
92
- return fig
93
-
94
-
95
- def create_treemap(user_annotations, total_records):
96
- sorted_users = sorted(user_annotations.items(), key=lambda x: x[1], reverse=True)
97
- color_scale = colors.qualitative.Pastel + colors.qualitative.Set3
98
-
99
- labels, parents, values, text, user_colors = [], [], [], [], []
100
-
101
- for i, (user, contribution) in enumerate(sorted_users):
102
- percentage = (contribution / total_records) * 100
103
- labels.append(user)
104
- parents.append("Annotations")
105
- values.append(contribution)
106
- text.append(f"{contribution} annotations<br>{percentage:.2f}%")
107
- user_colors.append(color_scale[i % len(color_scale)])
108
-
109
- labels.append("Annotations")
110
- parents.append("")
111
- values.append(total_records)
112
- text.append(f"Total: {total_records} annotations")
113
- user_colors.append("#FFFFFF")
114
-
115
- fig = go.Figure(
116
- go.Treemap(
117
- labels=labels,
118
- parents=parents,
119
- values=values,
120
- text=text,
121
- textinfo="label+text",
122
- hoverinfo="label+text+value",
123
- marker=dict(colors=user_colors, line=dict(width=2)),
124
- )
125
- )
126
-
127
- fig.update_layout(
128
- title_text="User contributions to the total end dataset",
129
- height=500,
130
- margin=dict(l=10, r=10, t=50, b=10),
131
- paper_bgcolor="#F0F0F0", # Light gray background
132
- plot_bgcolor="#F0F0F0", # Light gray background
133
- )
134
-
135
- return fig
136
-
137
- def get_datasets(client: rg.Argilla) -> List[rg.Dataset]:
138
- return client.datasets.list()
139
-
140
- datasets = get_datasets(client)
141
-
142
- def update_dashboard(dataset_idx: int| None = None):
143
- if dataset_idx is None:
144
- return [None, None, None]
145
-
146
- dataset = datasets[dataset_idx]
147
- progress = get_progress(dataset)
148
-
149
- gauge_chart = create_gauge_chart(progress)
150
- treemap = create_treemap(progress["users"], progress["total"])
151
-
152
- leaderboard_df = pd.DataFrame(
153
- list(progress["users"].items()), columns=["User", "Annotations"]
154
- )
155
-
156
- leaderboard_df = leaderboard_df.sort_values(
157
- "Annotations", ascending=False
158
- ).reset_index(drop=True)
159
-
160
- return gauge_chart, treemap, leaderboard_df
161
-
162
-
163
-
164
- with gr.Blocks() as demo:
165
- gr.Markdown("# Argilla Dataset Dashboard")
166
-
167
- datasets_dropdown = gr.Dropdown(label="Select your dataset")
168
- datasets_dropdown.choices = [(dataset.name, idx) for idx, dataset in enumerate(datasets)]
169
-
170
- def set_selected_dataset(dataset_idx) -> None:
171
- global selected_dataset
172
-
173
- dataset = datasets[dataset_idx]
174
- selected_dataset = dataset
175
-
176
-
177
- with gr.Row():
178
- gauge_output = gr.Plot(label="Overall Progress")
179
- treemap_output = gr.Plot(label="User contributions")
180
-
181
- with gr.Row():
182
- leaderboard_output = gr.Dataframe(
183
- label="Leaderboard", headers=["User", "Annotations"]
184
- )
185
-
186
- demo.load(
187
- update_dashboard,
188
- inputs=[datasets_dropdown],
189
- outputs=[gauge_output, treemap_output, leaderboard_output],
190
- every=5,
191
- )
192
 
193
- datasets_dropdown.change(
194
- update_dashboard,
195
- inputs=[datasets_dropdown],
196
- outputs=[gauge_output, treemap_output, leaderboard_output],
197
- )
198
 
 
199
 
200
- if __name__ == "__main__":
201
- demo.launch()
202
- # app dashboard from https://huggingface.co/spaces/davanstrien/argilla-progress/blob/main/app.py
203
- import os
204
- from typing import List
205
 
206
- import argilla as rg
207
- import gradio as gr
208
- import pandas as pd
209
- import plotly.colors as colors
210
- import plotly.graph_objects as go
211
 
212
- client = rg.Argilla(
213
- api_url=os.getenv("ARGILLA_API_URL"),
214
- api_key=os.getenv("ARGILLA_API_KEY"),
215
- )
216
-
217
- def get_progress(dataset: rg.Dataset) -> dict:
218
- dataset_progress = dataset.progress(with_users_distribution=True)
219
-
220
- total, completed = dataset_progress["total"], dataset_progress["completed"]
221
- progress = (completed / total) * 100 if total > 0 else 0
222
-
223
- return {
224
- "total": total,
225
- "annotated": completed,
226
- "progress": progress,
227
- "users": {
228
- username: user_progress["completed"].get("submitted")
229
- for username, user_progress in dataset_progress["users"].items()
230
- }
231
- }
232
-
233
-
234
- def create_gauge_chart(progress):
235
- fig = go.Figure(
236
- go.Indicator(
237
- mode="gauge+number+delta",
238
- value=progress["progress"],
239
- title={"text": "Dataset Annotation Progress", "font": {"size": 24}},
240
- delta={"reference": 100, "increasing": {"color": "RebeccaPurple"}},
241
- number={"font": {"size": 40}, "valueformat": ".1f", "suffix": "%"},
242
- gauge={
243
- "axis": {"range": [None, 100], "tickwidth": 1, "tickcolor": "darkblue"},
244
- "bar": {"color": "deepskyblue"},
245
- "bgcolor": "white",
246
- "borderwidth": 2,
247
- "bordercolor": "gray",
248
- "steps": [
249
- {"range": [0, progress["progress"]], "color": "royalblue"},
250
- {"range": [progress["progress"], 100], "color": "lightgray"},
251
- ],
252
- "threshold": {
253
- "line": {"color": "red", "width": 4},
254
- "thickness": 0.75,
255
- "value": 100,
256
- },
257
- },
258
- )
259
- )
260
 
261
  fig.update_layout(
262
- annotations=[
263
- dict(
264
- text=(
265
- f"Total records: {progress['total']}<br>"
266
- f"Annotated: {progress['annotated']} ({progress['progress']:.1f}%)<br>"
267
- f"Remaining: {progress['total'] - progress['annotated']} ({100 - progress['progress']:.1f}%)"
268
- ),
269
- # x=0.5,
270
- # y=-0.2,
271
- showarrow=False,
272
- xref="paper",
273
- yref="paper",
274
- font=dict(size=16),
275
- )
276
- ],
277
- )
278
 
279
- fig.add_annotation(
280
- text=(
281
- f"Current Progress: {progress['progress']:.1f}% complete<br>"
282
- f"({progress['annotated']} out of {progress['total']} records annotated)"
283
  ),
284
- xref="paper",
285
- yref="paper",
286
- x=0.5,
287
- y=1.1,
288
- showarrow=False,
289
- font=dict(size=18),
290
- align="center",
291
- )
292
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
293
  return fig
294
 
295
 
296
- def create_treemap(user_annotations, total_records):
 
297
  sorted_users = sorted(user_annotations.items(), key=lambda x: x[1], reverse=True)
298
  color_scale = colors.qualitative.Pastel + colors.qualitative.Set3
299
 
300
- labels, parents, values, text, user_colors = [], [], [], [], []
301
 
302
  for i, (user, contribution) in enumerate(sorted_users):
303
- percentage = (contribution / total_records) * 100
304
  labels.append(user)
305
- parents.append("Annotations")
306
  values.append(contribution)
307
- text.append(f"{contribution} annotations<br>{percentage:.2f}%")
308
  user_colors.append(color_scale[i % len(color_scale)])
309
 
310
- labels.append("Annotations")
311
- parents.append("")
312
- values.append(total_records)
313
- text.append(f"Total: {total_records} annotations")
314
- user_colors.append("#FFFFFF")
315
-
316
  fig = go.Figure(
317
- go.Treemap(
318
  labels=labels,
319
- parents=parents,
320
  values=values,
321
- text=text,
322
- textinfo="label+text",
323
- hoverinfo="label+text+value",
324
- marker=dict(colors=user_colors, line=dict(width=2)),
325
  )
326
  )
327
 
@@ -340,15 +163,17 @@ def get_datasets(client: rg.Argilla) -> List[rg.Dataset]:
340
 
341
  datasets = get_datasets(client)
342
 
343
- def update_dashboard(dataset_idx: int| None = None):
 
 
344
  if dataset_idx is None:
345
  return [None, None, None]
346
 
347
  dataset = datasets[dataset_idx]
348
  progress = get_progress(dataset)
349
 
350
- gauge_chart = create_gauge_chart(progress)
351
- treemap = create_treemap(progress["users"], progress["total"])
352
 
353
  leaderboard_df = pd.DataFrame(
354
  list(progress["users"].items()), columns=["User", "Annotations"]
@@ -358,15 +183,20 @@ def update_dashboard(dataset_idx: int| None = None):
358
  "Annotations", ascending=False
359
  ).reset_index(drop=True)
360
 
361
- return gauge_chart, treemap, leaderboard_df
362
 
363
 
364
 
365
  with gr.Blocks() as demo:
366
  gr.Markdown("# Argilla Dataset Dashboard")
367
 
368
- datasets_dropdown = gr.Dropdown(label="Select your dataset")
369
- datasets_dropdown.choices = [(dataset.name, idx) for idx, dataset in enumerate(datasets)]
 
 
 
 
 
370
 
371
  def set_selected_dataset(dataset_idx) -> None:
372
  global selected_dataset
@@ -376,25 +206,27 @@ with gr.Blocks() as demo:
376
 
377
 
378
  with gr.Row():
379
- gauge_output = gr.Plot(label="Overall Progress")
380
- treemap_output = gr.Plot(label="User contributions")
 
381
 
382
  with gr.Row():
383
  leaderboard_output = gr.Dataframe(
384
- label="Leaderboard", headers=["User", "Annotations"]
385
  )
 
386
 
387
  demo.load(
388
  update_dashboard,
389
  inputs=[datasets_dropdown],
390
- outputs=[gauge_output, treemap_output, leaderboard_output],
391
  every=5,
392
  )
393
 
394
  datasets_dropdown.change(
395
  update_dashboard,
396
  inputs=[datasets_dropdown],
397
- outputs=[gauge_output, treemap_output, leaderboard_output],
398
  )
399
 
400
 
 
24
  "annotated": completed,
25
  "progress": progress,
26
  "users": {
27
+ username: user_progress["completed"].get("submitted") + user_progress["pending"].get("submitted")
28
  for username, user_progress in dataset_progress["users"].items()
29
  }
30
  }
31
 
32
 
33
+ def create_progress_bar(progress):
34
+ top_labels = ['Completed', 'Pending']
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
35
 
36
+ colors = ['rgba(38, 24, 74, 0.8)',
37
+ # 'rgba(71, 58, 131, 0.8)',
38
+ # 'rgba(122, 120, 168, 0.8)', 'rgba(164, 163, 204, 0.85)',
39
+ 'rgba(190, 192, 213, 1)']
 
40
 
41
+ x_data = [[progress["annotated"], progress["total"] - progress["annotated"]]]
42
 
43
+ y_data = ['Progress']
 
 
 
 
44
 
45
+ fig = go.Figure()
 
 
 
 
46
 
47
+ for i in range(0, len(x_data[0])):
48
+ for xd, yd in zip(x_data, y_data):
49
+ fig.add_trace(go.Bar(
50
+ x=[xd[i]], y=[yd],
51
+ orientation='h',
52
+ marker=dict(
53
+ color=colors[i],
54
+ line=dict(color='rgb(248, 248, 249)', width=1)
55
+ ),
56
+ hoverinfo='text',
57
+ hovertext=f"{top_labels[i]} records: {xd[i]}"
58
+ ))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
59
 
60
  fig.update_layout(
61
+ xaxis=dict(
62
+ showgrid=False,
63
+ showline=False,
64
+ showticklabels=False,
65
+ zeroline=False,
66
+ domain=[0.15, 1]
 
 
 
 
 
 
 
 
 
 
67
 
 
 
 
 
68
  ),
69
+ yaxis=dict(
70
+ showgrid=False,
71
+ showline=False,
72
+ showticklabels=False,
73
+ zeroline=False,
74
+ domain=[0.15, 0.5]
75
+ ),
76
+ barmode='stack',
77
+ paper_bgcolor='rgb(248, 248, 255)',
78
+ plot_bgcolor='rgb(248, 248, 255)',
79
+ margin=dict(l=120, r=10, t=140, b=80),
80
+ showlegend=False
81
+ )
82
+
83
+ annotations = []
84
+
85
+ for yd, xd in zip(y_data, x_data):
86
+ # labeling the y-axis
87
+ annotations.append(dict(xref='paper', yref='y',
88
+ x=0.14, y=yd,
89
+ xanchor='right',
90
+ text=str(yd),
91
+ font=dict(family='Arial', size=14,
92
+ color='rgb(67, 67, 67)'),
93
+ showarrow=False, align='right'))
94
+ # labeling the first percentage of each bar (x_axis)
95
+ annotations.append(dict(xref='x', yref='y',
96
+ x=xd[0] / 2, y=yd,
97
+ text=str(xd[0]),
98
+ font=dict(family='Arial', size=14,
99
+ color='rgb(248, 248, 255)'),
100
+ showarrow=False))
101
+ # # labeling the first Likert scale (on the top)
102
+ # if yd == y_data[-1]:
103
+ # annotations.append(dict(xref='x', yref='paper',
104
+ # x=xd[0] / 2, y=1.1,
105
+ # text=top_labels[0],
106
+ # font=dict(family='Arial', size=14,
107
+ # color='rgb(67, 67, 67)'),
108
+ # showarrow=False))
109
+ space = xd[0]
110
+ for i in range(1, len(xd)):
111
+ # labeling the rest of percentages for each bar (x_axis)
112
+ annotations.append(dict(xref='x', yref='y',
113
+ x=space + (xd[i]/2), y=yd,
114
+ text=str(xd[i]),
115
+ font=dict(family='Arial', size=14,
116
+ color='rgb(248, 248, 255)'),
117
+ showarrow=False))
118
+ # # labeling the Likert scale
119
+ # if yd == y_data[-1]:
120
+ # annotations.append(dict(xref='x', yref='paper',
121
+ # x=space + (xd[i]/2), y=1.1,
122
+ # text=top_labels[i],
123
+ # font=dict(family='Arial', size=14,
124
+ # color='rgb(67, 67, 67)'),
125
+ # showarrow=False))
126
+ space += xd[i]
127
+
128
+ fig.update_layout(annotations=annotations, height=80)
129
  return fig
130
 
131
 
132
+
133
+ def create_piechart(user_annotations):
134
  sorted_users = sorted(user_annotations.items(), key=lambda x: x[1], reverse=True)
135
  color_scale = colors.qualitative.Pastel + colors.qualitative.Set3
136
 
137
+ labels, values, user_colors = [], [], []
138
 
139
  for i, (user, contribution) in enumerate(sorted_users):
 
140
  labels.append(user)
 
141
  values.append(contribution)
 
142
  user_colors.append(color_scale[i % len(color_scale)])
143
 
 
 
 
 
 
 
144
  fig = go.Figure(
145
+ go.Pie(
146
  labels=labels,
 
147
  values=values,
 
 
 
 
148
  )
149
  )
150
 
 
163
 
164
  datasets = get_datasets(client)
165
 
166
+ from typing import Optional
167
+
168
+ def update_dashboard(dataset_idx: Optional[int] = None):
169
  if dataset_idx is None:
170
  return [None, None, None]
171
 
172
  dataset = datasets[dataset_idx]
173
  progress = get_progress(dataset)
174
 
175
+ progress_bar = create_progress_bar(progress)
176
+ piechart = create_piechart(progress["users"])
177
 
178
  leaderboard_df = pd.DataFrame(
179
  list(progress["users"].items()), columns=["User", "Annotations"]
 
183
  "Annotations", ascending=False
184
  ).reset_index(drop=True)
185
 
186
+ return progress_bar, piechart, leaderboard_df
187
 
188
 
189
 
190
  with gr.Blocks() as demo:
191
  gr.Markdown("# Argilla Dataset Dashboard")
192
 
193
+ dataset_choices = [(dataset.name, idx) for idx, dataset in enumerate(datasets)]
194
+ datasets_dropdown = gr.Dropdown(
195
+ choices=dataset_choices,
196
+ label="Select your dataset",
197
+ value=0,
198
+ visible=True
199
+ )
200
 
201
  def set_selected_dataset(dataset_idx) -> None:
202
  global selected_dataset
 
206
 
207
 
208
  with gr.Row():
209
+ progress_bar_output = gr.Plot(label="Overall Progress")
210
+
211
+ gr.Markdown("## Contributor Leaderboard")
212
 
213
  with gr.Row():
214
  leaderboard_output = gr.Dataframe(
215
+ headers=["User", "Submitted records"]
216
  )
217
+ piechart_output = gr.Plot(label="User contributions")
218
 
219
  demo.load(
220
  update_dashboard,
221
  inputs=[datasets_dropdown],
222
+ outputs=[progress_bar_output, piechart_output, leaderboard_output],
223
  every=5,
224
  )
225
 
226
  datasets_dropdown.change(
227
  update_dashboard,
228
  inputs=[datasets_dropdown],
229
+ outputs=[progress_bar_output, piechart_output, leaderboard_output],
230
  )
231
 
232