emsesc commited on
Commit
4ad4863
·
1 Parent(s): ffc8ed8

redo leaderboard

Browse files
app.py CHANGED
@@ -1,7 +1,11 @@
1
  from dash import Dash, html, dcc, Input, Output, State
2
  import pandas as pd
3
  import dash_mantine_components as dmc
4
- from graphs.leaderboard import create_leaderboard, get_top_n_leaderboard, render_table, render_table_content
 
 
 
 
5
 
6
  # Initialize the app
7
  app = Dash()
@@ -10,160 +14,375 @@ server = app.server
10
  # Load pre-processed data frames
11
  filtered_df = pd.read_pickle("data_frames/filtered_df.pkl")
12
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13
  # Create a dcc slider for time range selection by year
14
- created_slider = dcc.Slider(
15
- id='created-slider',
16
- min=filtered_df['time'].min().year,
17
- max=filtered_df['time'].max().year,
18
- marks={year: str(year) for year in range(filtered_df['time'].min().year, filtered_df['time'].max().year + 1)},
19
- step=1,
20
- tooltip={"placement": "bottom", "always_visible": True},
21
- updatemode='mouseup',
 
 
 
 
 
 
 
 
 
 
 
22
  )
23
 
24
  # App layout
25
  app.layout = dmc.MantineProvider(
26
- theme={"colorScheme": "light",
27
- "primaryColor": "blue",
28
- "fontFamily": "Inter, sans-serif"},
29
- children=[html.Div(
30
- [
 
31
  html.Div(
32
  [
33
- html.Div(children='Visualizing the Open Model Ecosystem', style={'fontSize': 28, 'fontWeight': 'bold', 'marginBottom': 6}),
34
- html.Div(children='An interactive dashboard to explore trends in open models on Hugging Face', style={'fontSize': 16, 'marginBottom': 12}),
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
35
  html.Div(
36
  children=[
37
- html.A(
38
- "Data Provenance Initiative",
39
- href="https://www.dataprovenance.org/",
40
- target="_blank",
41
  style={
42
- 'display': 'inline-block',
43
- 'padding': '4px 14px',
44
- 'fontSize': 13,
45
- 'color': 'white',
46
- 'border': 'none',
47
- 'backgroundColor': '#228BE6',
48
- 'borderRadius': '18px',
49
- 'textDecoration': 'none',
50
- 'fontWeight': 'bold',
51
- 'boxShadow': '0 2px 8px rgba(37,99,235,0.08)',
52
- 'marginLeft': '6px',
53
- 'marginBottom': '4px',
54
- 'transition': 'background 0.2s',
55
- 'cursor': 'pointer'
56
- }
57
- )
58
  ],
59
- style={'fontSize': 14, 'marginBottom': 12}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
60
  ),
61
- html.Hr(style={'marginTop': 8, 'marginBottom': 8}),
62
- html.Div(children='Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry\'s standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.', style={'fontSize': 14, 'marginBottom': 12, 'marginLeft': 100, 'marginRight': 100}),
63
- ],
64
- style={'textAlign': 'center'}
65
- ),
66
- html.Div(
67
- children=[
68
- dmc.SegmentedControl(
69
- id="segmented",
70
- value="all-time",
71
- data=[
72
- {"value": "one-year", "label": "One Year Window"},
73
- {"value": "all-time", "label": "All Time"},
74
- ],
75
- mb=10,
76
- ),
77
- html.Span(id="global-toggle-status", style={"marginLeft": "8px"}),
78
- created_slider,
79
- html.Div(children='This is an explanation of the filters on this block.', style={'fontSize': 12, 'marginTop': 20, 'marginLeft': 10, 'marginRight': 10}),
80
- ],
81
- style={
82
- 'backgroundColor': 'white',
83
- 'borderRadius': '18px',
84
- 'boxShadow': '0 4px 24px rgba(0,0,0,0.10)',
85
- 'padding': '32px',
86
- 'margin': '32px auto',
87
- 'maxWidth': '1000px',
88
- }
89
- ),
90
- html.Div(
91
- [
92
- dcc.Tabs(children=[ # wrap Tabs here
93
- dcc.Tab(label='Countries', children=[
94
- create_leaderboard(
95
- filtered_df, "countries"
96
- )
97
- ]),
98
- dcc.Tab(label='Developers', children=[
99
- create_leaderboard(
100
- filtered_df, "developers"
101
- )
102
- ]),
103
- dcc.Tab(label='Models', children=[
104
- create_leaderboard(
105
- filtered_df, "models"
106
- )
107
- ]),
108
- ]),
109
  ],
110
  style={
111
- 'backgroundColor': 'white',
112
- 'borderRadius': '18px',
113
- 'boxShadow': '0 4px 24px rgba(0,0,0,0.10)',
114
- 'padding': '32px',
115
- 'margin': '32px auto',
116
- 'maxWidth': '1250px',
117
- }
118
  )
119
  ],
120
- style={'fontFamily': 'Inter', 'backgroundColor': '#f7f7fa', 'minHeight': '100vh'}
121
- )])
122
 
123
  # Callbacks for interactivity
 
 
 
 
 
 
 
124
 
125
- # Model Market Share Tab
126
- # On slider change, update output text
127
- # @app.callback(
128
- # Output('output-container-range-slider', 'children'),
129
- # [Input('time-slider', 'value')]
130
- # )
131
- # def update_output(value):
132
- # if value and len(value) == 2:
133
- # start_time = pd.to_datetime(value[0], unit='s').strftime("%b %d, %Y")
134
- # end_time = pd.to_datetime(value[1], unit='s').strftime("%b %d, %Y")
135
- # return f"Selected time range: {start_time} to {end_time}"
136
- # return "Select a time range"
137
-
138
- # On slider change, update world map
139
- # @app.callback(
140
- # Output('world-map-with-slider', 'figure'),
141
- # Input('created-slider', 'value')
142
- # )
143
- # def update_world_map(value):
144
- # # Filter by created year
145
- # if value is None:
146
- # return world_map
147
-
148
- # created_after = f"{int(value)}-01-01"
149
- # updated_fig = create_world_map(
150
- # filtered_df,
151
- # created_after=created_after
152
- # )
153
- # return updated_fig
154
-
155
- @app.callback(
156
- Output("top_countries-table", "children"),
157
- Output("top_countries-toggle", "children"),
158
- Input("top_countries-toggle", "n_clicks"),
159
- State("top_countries-toggle", "children"),
160
- )
161
- def update_top_countries(n_clicks, current_label):
162
- print(n_clicks, current_label)
163
- # Handle initial page load
164
  if current_label is None:
165
- current_label = "▼ Show Top 50"
166
 
 
167
  if n_clicks == 0:
168
  top_n = 10
169
  new_label = current_label
@@ -174,58 +393,79 @@ def update_top_countries(n_clicks, current_label):
174
  else:
175
  top_n, new_label = 10, "▼ Show Top 50"
176
 
177
- df, download_df = get_top_n_leaderboard(filtered_df, "org_country_single", top_n)
178
- return render_table_content(df, download_df, chip_color="#FCE8E6", filename="top_countries"), new_label
 
 
 
 
 
179
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
180
 
181
  @app.callback(
182
  Output("top_developers-table", "children"),
183
  Output("top_developers-toggle", "children"),
184
  Input("top_developers-toggle", "n_clicks"),
 
185
  State("top_developers-toggle", "children"),
186
  )
187
- def update_top_developers(n_clicks, current_label):
188
- # Handle initial page load
189
- if current_label is None:
190
- current_label = "▼ Show More"
191
-
192
- if n_clicks == 0:
193
- top_n = 10
194
- new_label = current_label
195
- elif "Show Top 50" in current_label:
196
- top_n, new_label = 50, "▼ Show Top 100"
197
- elif "Show Top 100" in current_label:
198
- top_n, new_label = 100, "▲ Show Less"
199
- else:
200
- top_n, new_label = 10, "▼ Show Top 50"
201
-
202
- df, download_df = get_top_n_leaderboard(filtered_df, "author", top_n)
203
- return render_table_content(df, download_df, chip_color="#E6F4EA", filename="top_developers"), new_label
204
 
205
  @app.callback(
206
  Output("top_models-table", "children"),
207
  Output("top_models-toggle", "children"),
208
  Input("top_models-toggle", "n_clicks"),
 
209
  State("top_models-toggle", "children"),
210
  )
211
- def update_top_models(n_clicks, current_label):
212
- # Handle initial page load
213
- if current_label is None:
214
- current_label = "▼ Show More"
 
 
 
 
 
 
215
 
216
- if n_clicks == 0:
217
- top_n = 10
218
- new_label = current_label
219
- elif "Show Top 50" in current_label:
220
- top_n, new_label = 50, "▼ Show Top 100"
221
- elif "Show Top 100" in current_label:
222
- top_n, new_label = 100, " Show Less"
223
- else:
224
- top_n, new_label = 10, "▼ Show Top 50"
225
 
226
- df, download_df = get_top_n_leaderboard(filtered_df, "model", top_n)
227
- return render_table_content(df, download_df, chip_color="#E8F0FE", filename="top_models"), new_label
228
 
229
  # Run the app
230
- if __name__ == '__main__':
231
  app.run(debug=True)
 
1
  from dash import Dash, html, dcc, Input, Output, State
2
  import pandas as pd
3
  import dash_mantine_components as dmc
4
+ from graphs.leaderboard import (
5
+ create_leaderboard,
6
+ get_top_n_leaderboard,
7
+ render_table_content,
8
+ )
9
 
10
  # Initialize the app
11
  app = Dash()
 
14
  # Load pre-processed data frames
15
  filtered_df = pd.read_pickle("data_frames/filtered_df.pkl")
16
 
17
+ # Create a dcc slider for time range selection by year (readable marks)
18
+ start_dt = filtered_df["time"].min()
19
+ end_dt = filtered_df["time"].max()
20
+ start_ts = int(start_dt.timestamp())
21
+ end_ts = int(end_dt.timestamp())
22
+
23
+ marks = []
24
+ # Add start label (e.g. "Jan 2020")
25
+ marks.append({"value": start_ts, "label": start_dt.strftime("%b %Y")})
26
+ # Add yearly marks between start and end (e.g. "2021", "2022")
27
+ for yr in range(start_dt.year, end_dt.year + 1):
28
+ yr_ts = int(pd.Timestamp(year=yr, month=1, day=1).timestamp())
29
+ start_yr = int(pd.Timestamp(year=start_dt.year, month=1, day=1).timestamp())
30
+ if yr_ts != start_yr and yr_ts != end_ts:
31
+ marks.append({"value": yr_ts, "label": str(yr)})
32
+ # Add end label (e.g. "Dec 2024")
33
+ marks.append({"value": end_ts, "label": end_dt.strftime("%b %Y")})
34
+
35
  # Create a dcc slider for time range selection by year
36
+ time_slider = dmc.RangeSlider(
37
+ id="time-slider",
38
+ min=start_ts,
39
+ max=end_ts,
40
+ value=[
41
+ start_ts,
42
+ end_ts,
43
+ ],
44
+ step=24 * 60 * 60,
45
+ color="#AC482A",
46
+ size="md",
47
+ radius="xl",
48
+ marks=marks,
49
+ style={"width": "70%", "margin": "0 auto"},
50
+ labelAlwaysOn=False,
51
+ # thumbChildren=[
52
+ # dmc.Text(id="time-slider-thumb-from-label", size="xs", children="Hello"),
53
+ # dmc.Text(id="time-slider-thumb-to-label", size="xs"),
54
+ # ]
55
  )
56
 
57
  # App layout
58
  app.layout = dmc.MantineProvider(
59
+ theme={
60
+ "colorScheme": "light",
61
+ "primaryColor": "blue",
62
+ "fontFamily": "Inter, sans-serif",
63
+ },
64
+ children=[
65
  html.Div(
66
  [
67
+ # Header
68
+ html.Div(
69
+ [
70
+ html.Div(
71
+ [
72
+ html.Div(
73
+ [
74
+ html.Div(
75
+ children="Visualizing the Open Model Ecosystem",
76
+ style={
77
+ "fontSize": 22,
78
+ "fontWeight": "700",
79
+ "lineHeight": "1.1",
80
+ },
81
+ ),
82
+ html.Div(
83
+ children="An interactive dashboard to explore trends in open models on Hugging Face",
84
+ style={
85
+ "fontSize": 13,
86
+ "marginTop": 6,
87
+ "opacity": 0.9,
88
+ },
89
+ ),
90
+ ],
91
+ style={
92
+ "display": "flex",
93
+ "flexDirection": "column",
94
+ "justifyContent": "center",
95
+ },
96
+ ),
97
+ html.Div(
98
+ [
99
+ html.A(
100
+ children=[
101
+ html.Img(
102
+ src="assets/images/dpi-logo.svg",
103
+ style={
104
+ "height": "28px",
105
+ "verticalAlign": "middle",
106
+ "paddingRight": "8px",
107
+ },
108
+ ),
109
+ "Data Provenance Initiative",
110
+ ],
111
+ href="https://www.dataprovenance.org/",
112
+ target="_blank",
113
+ style={
114
+ "display": "inline-block",
115
+ "padding": "6px 14px",
116
+ "fontSize": 13,
117
+ "color": "#082030",
118
+ "backgroundColor": "#ffffff",
119
+ "borderRadius": "18px",
120
+ "fontWeight": "700",
121
+ "textDecoration": "none",
122
+ "marginRight": "12px",
123
+ },
124
+ ),
125
+ html.A(
126
+ children=[
127
+ html.Img(
128
+ src="assets/images/Hf-logo-with-title.svg",
129
+ style={
130
+ "height": "30px",
131
+ "verticalAlign": "middle",
132
+ },
133
+ )
134
+ ],
135
+ href="https://huggingface.co/",
136
+ target="_blank",
137
+ style={
138
+ "display": "inline-flex",
139
+ "padding": "6px 14px",
140
+ "alignItems": "center",
141
+ "backgroundColor": "#ffffff",
142
+ "borderRadius": "18px",
143
+ "textDecoration": "none",
144
+ },
145
+ ),
146
+ ],
147
+ style={"display": "flex", "alignItems": "center"},
148
+ ),
149
+ ],
150
+ style={
151
+ "marginLeft": "50px",
152
+ "marginRight": "50px",
153
+ "display": "flex",
154
+ "justifyContent": "space-between",
155
+ "alignItems": "center",
156
+ "padding": "18px 24px",
157
+ "gap": "24px",
158
+ },
159
+ ),
160
+ ],
161
+ style={
162
+ "backgroundColor": "#082030",
163
+ "color": "white",
164
+ "width": "100%",
165
+ },
166
+ ),
167
+ # Intro / description below header (kept but styled to match layout)
168
+ # Title
169
+ html.Div(
170
+ children="Model Leaderboard", # Change this to your desired title
171
+ style={
172
+ "fontSize": 40,
173
+ "fontWeight": "700",
174
+ "textAlign": "center",
175
+ "marginTop": 20,
176
+ "marginBottom": 20,
177
+ },
178
+ ),
179
+ # Button
180
  html.Div(
181
  children=[
182
+ html.Button(
183
+ "Read the paper", # Change this to your desired button text
184
+ id="my-button",
 
185
  style={
186
+ "padding": "10px 20px",
187
+ "fontSize": 16,
188
+ "margin": "0 auto",
189
+ "display": "block",
190
+ "backgroundColor": "#AC482A",
191
+ "color": "white",
192
+ "border": "none",
193
+ "borderRadius": "5px",
194
+ "cursor": "pointer",
195
+ },
196
+ ),
 
 
 
 
 
197
  ],
198
+ style={"textAlign": "center", "marginBottom": 20},
199
+ ),
200
+ html.Div(
201
+ children="Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s...",
202
+ style={
203
+ "fontSize": 14,
204
+ "marginTop": 18,
205
+ "marginBottom": 12,
206
+ "marginLeft": 100,
207
+ "marginRight": 100,
208
+ "textAlign": "center",
209
+ },
210
+ ),
211
+ # Main content (filters + tabs)
212
+ html.Div(
213
+ children=[
214
+ html.Div(
215
+ [
216
+ html.Div(
217
+ "Select Window",
218
+ style={
219
+ "fontWeight": "700",
220
+ "marginBottom": 8,
221
+ "fontSize": 14,
222
+ },
223
+ ),
224
+ dmc.SegmentedControl(
225
+ id="segmented",
226
+ value="all-downloads",
227
+ color="#AC482A",
228
+ transitionDuration=200,
229
+ data=[
230
+ {
231
+ "value": "all-downloads",
232
+ "label": "All Downloads",
233
+ },
234
+ {
235
+ "value": "filtered-downloads",
236
+ "label": "Filtered Downloads",
237
+ },
238
+ ],
239
+ mb=10,
240
+ ),
241
+ html.Span(
242
+ id="global-toggle-status",
243
+ style={
244
+ "marginLeft": "8px",
245
+ "display": "inline-block",
246
+ "marginTop": 6,
247
+ },
248
+ ),
249
+ ],
250
+ style={"flex": 1, "minWidth": "220px"},
251
+ ),
252
+ html.Div(
253
+ [
254
+ html.Div(
255
+ "Select Time Range",
256
+ style={
257
+ "fontWeight": "700",
258
+ "marginBottom": 8,
259
+ "fontSize": 14,
260
+ },
261
+ ),
262
+ time_slider,
263
+ ],
264
+ style={"flex": 2, "minWidth": "320px"},
265
+ ),
266
+ ],
267
+ style={
268
+ "display": "flex",
269
+ "gap": "24px",
270
+ "padding": "32px",
271
+ "alignItems": "flex-start",
272
+ # 'margin': '24px auto 64px', # centered horizontally
273
+ "marginLeft": "100px",
274
+ "marginRight": "100px",
275
+ "backgroundColor": "#FFFBF9",
276
+ "borderRadius": "18px",
277
+ },
278
+ ),
279
+ html.Div(
280
+ [
281
+ dcc.Tabs(
282
+ id="leaderboard-tabs",
283
+ value="Countries",
284
+ children=[ # wrap Tabs here
285
+ dcc.Tab(
286
+ label="Countries",
287
+ value="Countries",
288
+ style={
289
+ "backgroundColor": "transparent",
290
+ "border": "none",
291
+ "padding": "10px 18px",
292
+ "color": "#6B7280",
293
+ "fontWeight": "500",
294
+ },
295
+ selected_style={
296
+ "backgroundColor": "transparent",
297
+ "border": "none",
298
+ "padding": "10px 18px",
299
+ "fontWeight": "700",
300
+ "borderBottom": "3px solid #082030", # underline only
301
+ },
302
+ children=[
303
+ create_leaderboard(filtered_df, "countries")
304
+ ],
305
+ ),
306
+ dcc.Tab(
307
+ label="Developers",
308
+ value="Developers",
309
+ style={
310
+ "backgroundColor": "transparent",
311
+ "border": "none",
312
+ "padding": "10px 18px",
313
+ "color": "#6B7280",
314
+ "fontWeight": "500",
315
+ },
316
+ selected_style={
317
+ "backgroundColor": "transparent",
318
+ "border": "none",
319
+ "padding": "10px 18px",
320
+ "fontWeight": "700",
321
+ "borderBottom": "3px solid #082030",
322
+ },
323
+ children=[
324
+ create_leaderboard(filtered_df, "developers")
325
+ ],
326
+ ),
327
+ dcc.Tab(
328
+ label="Models",
329
+ value="Models",
330
+ style={
331
+ "backgroundColor": "transparent",
332
+ "border": "none",
333
+ "padding": "10px 18px",
334
+ "color": "#6B7280",
335
+ "fontWeight": "500",
336
+ },
337
+ selected_style={
338
+ "backgroundColor": "transparent",
339
+ "border": "none",
340
+ "padding": "10px 18px",
341
+ "fontWeight": "700",
342
+ "borderBottom": "3px solid #082030",
343
+ },
344
+ children=[
345
+ create_leaderboard(filtered_df, "models")
346
+ ],
347
+ ),
348
+ ],
349
+ ),
350
+ ],
351
+ style={
352
+ "borderRadius": "18px",
353
+ "padding": "32px",
354
+ "marginTop": "12px",
355
+ "marginBottom": "64px",
356
+ "marginLeft": "50px",
357
+ "marginRight": "50px",
358
+ # 'maxWidth': '1250px',
359
+ },
360
  ),
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
361
  ],
362
  style={
363
+ "fontFamily": "Inter",
364
+ "backgroundColor": "#ffffff",
365
+ "minHeight": "100vh",
366
+ },
 
 
 
367
  )
368
  ],
369
+ )
 
370
 
371
  # Callbacks for interactivity
372
+ # -- helper utilities to consolidate duplicated callback logic --
373
+ def _apply_time_slider(slider_value):
374
+ if slider_value and len(slider_value) == 2:
375
+ start = pd.to_datetime(slider_value[0], unit="s")
376
+ end = pd.to_datetime(slider_value[1], unit="s")
377
+ return filtered_df[(filtered_df["time"] >= start) & (filtered_df["time"] <= end)]
378
+ return filtered_df
379
 
380
+ def _leaderboard_callback_logic(n_clicks, slider_value, current_label, group_col, filename, default_label="▼ Show Top 50", chip_color="#F0F9FF"):
381
+ # Normalize label on first load
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
382
  if current_label is None:
383
+ current_label = default_label
384
 
385
+ # Determine top_n and next label
386
  if n_clicks == 0:
387
  top_n = 10
388
  new_label = current_label
 
393
  else:
394
  top_n, new_label = 10, "▼ Show Top 50"
395
 
396
+ # Apply time filter and build table
397
+ df_time = _apply_time_slider(slider_value)
398
+ df, download_df = get_top_n_leaderboard(df_time, group_col, top_n)
399
+ return render_table_content(df, download_df, chip_color=chip_color, filename=filename), new_label
400
+ # -- end helpers --
401
+
402
+ # ...existing code...
403
 
404
+ # Callbacks for interactivity (modularized)
405
+ @app.callback(
406
+ Output("top_countries-table", "children"),
407
+ Output("top_countries-toggle", "children"),
408
+ Input("top_countries-toggle", "n_clicks"),
409
+ Input("time-slider", "value"),
410
+ State("top_countries-toggle", "children"),
411
+ )
412
+ def update_top_countries(n_clicks, slider_value, current_label):
413
+ return _leaderboard_callback_logic(
414
+ n_clicks,
415
+ slider_value,
416
+ current_label,
417
+ group_col="org_country_single",
418
+ filename="top_countries",
419
+ default_label="▼ Show Top 50",
420
+ chip_color="#F0F9FF",
421
+ )
422
 
423
  @app.callback(
424
  Output("top_developers-table", "children"),
425
  Output("top_developers-toggle", "children"),
426
  Input("top_developers-toggle", "n_clicks"),
427
+ Input("time-slider", "value"),
428
  State("top_developers-toggle", "children"),
429
  )
430
+ def update_top_developers(n_clicks, slider_value, current_label):
431
+ return _leaderboard_callback_logic(
432
+ n_clicks,
433
+ slider_value,
434
+ current_label,
435
+ group_col="author",
436
+ filename="top_developers",
437
+ default_label="▼ Show More",
438
+ chip_color="#F0F9FF",
439
+ )
 
 
 
 
 
 
 
440
 
441
  @app.callback(
442
  Output("top_models-table", "children"),
443
  Output("top_models-toggle", "children"),
444
  Input("top_models-toggle", "n_clicks"),
445
+ Input("time-slider", "value"),
446
  State("top_models-toggle", "children"),
447
  )
448
+ def update_top_models(n_clicks, slider_value, current_label):
449
+ return _leaderboard_callback_logic(
450
+ n_clicks,
451
+ slider_value,
452
+ current_label,
453
+ group_col="model",
454
+ filename="top_models",
455
+ default_label="▼ Show More",
456
+ chip_color="#F0F9FF",
457
+ )
458
 
459
+ @app.callback(
460
+ Output("time-slider", "label"),
461
+ Input("time-slider", "value")
462
+ )
463
+ def update_range_labels(values):
464
+ start_label = pd.to_datetime(values[0], unit="s").strftime("%b %Y")
465
+ end_label = pd.to_datetime(values[1], unit="s").strftime("%b %Y")
466
+ return [start_label, end_label]
 
467
 
 
 
468
 
469
  # Run the app
470
+ if __name__ == "__main__":
471
  app.run(debug=True)
assets/images/Hf-logo-with-title.svg ADDED
assets/images/dpi-logo.svg ADDED
graphs/leaderboard.py CHANGED
@@ -5,49 +5,49 @@ import dash_mantine_components as dmc
5
  import base64
6
 
7
  button_style = {
8
- "display": "inline-block",
9
- "marginBottom": "10px",
10
- "marginRight": "15px",
11
- "marginTop": "30px",
12
- "padding": "6px 16px",
13
- "backgroundColor": "#2196F3",
14
- "color": "white",
15
- "borderRadius": "6px",
16
- "textDecoration": "none",
17
- "fontWeight": "bold",
18
- "fontSize": "14px"
19
- }
20
 
21
  country_icon_map = {
22
- "USA": "🇺🇸",
23
- "China": "🇨🇳",
24
- "Germany": "🇩🇪",
25
- "France": "🇫🇷",
26
- "India": "🇮🇳",
27
- "Italy": "🇮🇹",
28
- "Japan": "🇯🇵",
29
- "South Korea": "🇰🇷",
30
- "United Kingdom": "🇬🇧",
31
- "Canada": "🇨🇦",
32
- "Brazil": "🇧🇷",
33
- "Australia": "🇦🇺",
34
- "Unknown": "❓",
35
- "Finland": "🇫🇮",
36
- "Lebanon": "🇱🇧",
37
- "Iceland": "🇮🇸",
38
- "Singapore": "🇸🇬",
39
- "Israel": "🇮🇱",
40
- "Iran": "🇮🇷",
41
- "Hong Kong": "🇭🇰",
42
- "Netherlands": "🇳🇱",
43
- "Chile": "🇨🇱",
44
- "Vietnam": "🇻🇳",
45
- "Russia": "🇷🇺",
46
- "Qatar": "🇶🇦",
47
- "Switzerland": "🇨🇭",
48
- "User": "👤",
49
- "International/Online": "🌐",
50
- }
51
 
52
  company_icon_map = {
53
  "google": "../assets/icons/google.png",
@@ -60,9 +60,16 @@ company_icon_map = {
60
  meta_cols_map = {
61
  "org_country_single": ["org_country_single"],
62
  "author": ["org_country_single", "author", "merged_country_groups_single"],
63
- "model": ["org_country_single", "author", "merged_country_groups_single", "merged_modality", "downloads"]
 
 
 
 
 
 
64
  }
65
 
 
66
  # Chip renderer
67
  def chip(text, bg_color="#F0F0F0"):
68
  return html.Span(
@@ -74,12 +81,13 @@ def chip(text, bg_color="#F0F0F0"):
74
  "margin": "2px",
75
  "display": "inline-flex",
76
  "alignItems": "center",
77
- "fontSize": "14px"
78
- }
79
  )
80
 
 
81
  # Progress bar for % of total
82
- def progress_bar(percent, bar_color="#4CAF50"):
83
  return html.Div(
84
  style={
85
  "position": "relative",
@@ -111,11 +119,12 @@ def progress_bar(percent, bar_color="#4CAF50"):
111
  "fontSize": "12px",
112
  "lineHeight": "20px",
113
  "textAlign": "center",
114
- }
115
- )
116
- ]
117
  )
118
 
 
119
  # Helper to convert DataFrame to CSV and encode for download
120
  def df_to_download_link(df, filename):
121
  csv_string = df.to_csv(index=False)
@@ -124,103 +133,252 @@ def df_to_download_link(df, filename):
124
  html.A(
125
  children=dmc.ActionIcon(
126
  DashIconify(icon="mdi:download", width=24),
127
- size="lg"
 
128
  ),
129
  id=f"download-{filename}",
130
  download=f"{filename}.csv",
131
  href=f"data:text/csv;base64,{b64}",
132
  target="_blank",
133
  title="Download CSV",
134
- style={"padding": "6px 12px", "display": "inline-flex", "alignItems": "center", "justifyContent": "center"}
 
 
 
 
 
135
  ),
136
- style={"textAlign": "right"}
137
  )
138
 
 
139
  # Render multiple chips in one row
140
- def render_chips(metadata_list, chip_color="#F0F0F0"):
141
  chips = []
142
  for icon, name in metadata_list:
143
- if isinstance(icon, str) and icon.endswith(('.png', '.jpg', '.jpeg', '.svg')):
144
  chips.append(
145
- html.Span([
146
- html.Img(src=icon, style={"height": "18px", "marginRight": "6px"}),
147
- name
148
- ],
149
- style={
150
- "backgroundColor": chip_color,
151
- "padding": "4px 10px",
152
- "borderRadius": "12px",
153
- "margin": "2px",
154
- "display": "inline-flex",
155
- "alignItems": "left",
156
- "fontSize": "14px"
157
- })
 
 
 
 
158
  )
159
  else:
160
  chips.append(chip(f"{icon} {name}", chip_color))
161
  return html.Div(
162
- chips,
163
- style={"display": "flex", "flexWrap": "wrap", "justifyContent": "left"}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
164
  )
165
 
166
- def render_table_content(df, download_df, chip_color="#F0F0F0", bar_color="#4CAF50", filename="data"):
167
- return html.Div([
168
- html.Table([
169
- html.Thead(html.Tr([
170
- html.Th("Rank", style={"backgroundColor": "#F0F0F0", "textAlign": "left"}),
171
- html.Th("Name", style={"backgroundColor": "#F0F0F0", "textAlign": "left"}),
172
- html.Th("Metadata", style={"backgroundColor": "#F0F0F0", "textAlign": "left", "marginRight": "10px"}),
173
- html.Th("% of Total", style={"backgroundColor": "#F0F0F0", "textAlign": "left"})
174
- ])),
175
- html.Tbody([
176
- html.Tr([
177
- html.Td(idx+1, style={"textAlign": "center"}),
178
- html.Td(row["Name"], style={"textAlign": "left"}),
179
- html.Td(render_chips(row["Metadata"], chip_color)),
180
- html.Td(progress_bar(row["% of total"], bar_color), style={"textAlign": "center"})
181
- ]) for idx, row in df.iterrows()
182
- ])
183
- ], style={"borderCollapse": "collapse", "width": "100%"}),
184
- ])
185
 
186
  # Table renderer
187
- def render_table(df, download_df, title, chip_color="#F0F0F0", bar_color="#4CAF50", filename="data"):
188
- return html.Div(id=f"{filename}-div", children=[
189
- html.Div([
190
- html.H4(title, style={"textAlign": "left", "marginBottom": "10px", "fontSize": "20px", "display": "inline-block"}),
191
- df_to_download_link(download_df, filename)
192
- ], style={"display": "flex", "alignItems": "center", "justifyContent": "space-between"}),
193
- html.Div(id=f"{filename}-table", children=[
194
- html.Table([
195
- html.Thead(html.Tr([
196
- html.Th("Rank", style={"backgroundColor": "#F0F0F0", "textAlign": "left"}),
197
- html.Th("Name", style={"backgroundColor": "#F0F0F0", "textAlign": "left"}),
198
- html.Th("Metadata", style={"backgroundColor": "#F0F0F0", "textAlign": "left", "marginRight": "10px"}),
199
- html.Th("% of Total", style={"backgroundColor": "#F0F0F0", "textAlign": "left"})
200
- ])),
201
- html.Tbody([
202
- html.Tr([
203
- html.Td(idx+1, style={"textAlign": "center"}),
204
- html.Td(row["Name"], style={"textAlign": "left"}),
205
- html.Td(render_chips(row["Metadata"], chip_color)),
206
- html.Td(progress_bar(row["% of total"], bar_color), style={"textAlign": "center"})
207
- ]) for idx, row in df.iterrows()
208
- ])
209
- ], style={"borderCollapse": "collapse", "width": "100%", "border": "none"}),
210
- ]),
211
- html.Div([
212
- html.Button(
213
- "▼ Show Top 50",
214
- id=f"{filename}-toggle",
215
- n_clicks=0,
216
- style={**button_style, "border": "none"}
217
- )
218
- ], style={"marginTop": "5px", "textAlign": "left"})
219
- ], style={"marginBottom": "20px"})
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
220
 
221
  # Function to get top N leaderboard
222
  def get_top_n_leaderboard(filtered_df, group_col, top_n=10):
223
- top = filtered_df.groupby(group_col)["downloads"].sum().nlargest(top_n).reset_index().rename(columns={group_col: "Name", "downloads": "Total Value"})
 
 
 
 
 
 
224
  total_value = top["Total Value"].sum()
225
  top["% of total"] = top["Total Value"] / total_value * 100 if total_value else 0
226
 
@@ -245,7 +403,7 @@ def get_top_n_leaderboard(filtered_df, group_col, top_n=10):
245
  unique_vals = name_data[col].unique()
246
  meta_map[name][col] = list(unique_vals)
247
  download_map[name][col] = list(unique_vals)
248
-
249
  # Function to build metadata chips
250
  def build_metadata(nm):
251
  meta = meta_map.get(nm, {})
@@ -268,28 +426,30 @@ def get_top_n_leaderboard(filtered_df, group_col, top_n=10):
268
  chips.append((icon, a))
269
  # Downloads
270
  # Sum downloads if multiple entries
271
- total_downloads = sum(d for d in meta.get("downloads", []) if pd.notna(d)) # Check if d is not NaN
 
 
272
  if total_downloads:
273
  chips.append(("⬇️", f"{int(total_downloads):,}"))
274
 
275
  # Modality
276
  for m in meta.get("merged_modality", []):
277
  chips.append(("", m))
278
-
279
  # Estimated Parameters
280
  for p in meta.get("estimated_parameters", []):
281
  if pd.notna(p): # Check if p is not NaN
282
  if p >= 1e9:
283
- p_str = f"{p/1e9:.1f}B"
284
  elif p >= 1e6:
285
- p_str = f"{p/1e6:.1f}M"
286
  elif p >= 1e3:
287
- p_str = f"{p/1e3:.1f}K"
288
  else:
289
  p_str = str(p)
290
  chips.append(("⚙️", p_str))
291
  return chips
292
-
293
  # Function to create downloadable dataframe
294
  def build_download_metadata(nm):
295
  meta = download_map.get(nm, {})
@@ -305,7 +465,7 @@ def get_top_n_leaderboard(filtered_df, group_col, top_n=10):
305
  else:
306
  download_info[col] = ""
307
  return download_info
308
-
309
  # Apply metadata builder to top dataframe
310
  top["Metadata"] = top["Name"].astype(object).apply(build_metadata)
311
  download_info_list = [build_download_metadata(nm) for nm in download_top["Name"]]
@@ -314,27 +474,53 @@ def get_top_n_leaderboard(filtered_df, group_col, top_n=10):
314
 
315
  return top[["Name", "Metadata", "% of total"]], download_top
316
 
317
- def create_leaderboard(filtered_df, board_type, start_time=None, top_n=10):
318
- # Filter by time
319
- if start_time is not None:
320
- filtered_df = filtered_df[(filtered_df["created"] >= start_time) & (filtered_df["time"] >= start_time)]
321
 
 
322
  if filtered_df.empty:
323
  return html.Div("No data in selected range")
324
-
325
  # Merge HF and USA
326
- filtered_df["org_country_single"] = filtered_df["org_country_single"].replace({"HF": "United States of America"})
 
 
327
  # Merge International and Online
328
- filtered_df["org_country_single"] = filtered_df["org_country_single"].replace({"International": "International/Online", "Online": "International/Online"})
 
 
329
 
330
  # Build leaderboards
331
- top_countries, download_top_countries = get_top_n_leaderboard(filtered_df, "org_country_single", top_n)
332
- top_developers, download_top_developers = get_top_n_leaderboard(filtered_df, "author", top_n)
 
 
 
 
333
  top_models, download_top_models = get_top_n_leaderboard(filtered_df, "model", top_n)
334
 
335
  if board_type == "countries":
336
- return render_table(top_countries, download_top_countries, "Top Countries", chip_color="#FCE8E6", bar_color="#FF6F61", filename="top_countries")
 
 
 
 
 
 
 
337
  elif board_type == "developers":
338
- return render_table(top_developers, download_top_developers, "Top Developers", chip_color="#E6F4EA", bar_color="#4CAF50", filename="top_developers")
 
 
 
 
 
 
 
339
  else:
340
- return render_table(top_models, download_top_models, "Top Models", chip_color="#E8F0FE", bar_color="#2196F3", filename="top_models")
 
 
 
 
 
 
 
 
5
  import base64
6
 
7
  button_style = {
8
+ "display": "inline-block",
9
+ "marginBottom": "10px",
10
+ "marginRight": "15px",
11
+ "marginTop": "30px",
12
+ "padding": "6px 16px",
13
+ "backgroundColor": "#082030",
14
+ "color": "white",
15
+ "borderRadius": "6px",
16
+ "textDecoration": "none",
17
+ "fontWeight": "bold",
18
+ "fontSize": "14px",
19
+ }
20
 
21
  country_icon_map = {
22
+ "USA": "🇺🇸",
23
+ "China": "🇨🇳",
24
+ "Germany": "🇩🇪",
25
+ "France": "🇫🇷",
26
+ "India": "🇮🇳",
27
+ "Italy": "🇮🇹",
28
+ "Japan": "🇯🇵",
29
+ "South Korea": "🇰🇷",
30
+ "United Kingdom": "🇬🇧",
31
+ "Canada": "🇨🇦",
32
+ "Brazil": "🇧🇷",
33
+ "Australia": "🇦🇺",
34
+ "Unknown": "❓",
35
+ "Finland": "🇫🇮",
36
+ "Lebanon": "🇱🇧",
37
+ "Iceland": "🇮🇸",
38
+ "Singapore": "🇸🇬",
39
+ "Israel": "🇮🇱",
40
+ "Iran": "🇮🇷",
41
+ "Hong Kong": "🇭🇰",
42
+ "Netherlands": "🇳🇱",
43
+ "Chile": "🇨🇱",
44
+ "Vietnam": "🇻🇳",
45
+ "Russia": "🇷🇺",
46
+ "Qatar": "🇶🇦",
47
+ "Switzerland": "🇨🇭",
48
+ "User": "👤",
49
+ "International/Online": "🌐",
50
+ }
51
 
52
  company_icon_map = {
53
  "google": "../assets/icons/google.png",
 
60
  meta_cols_map = {
61
  "org_country_single": ["org_country_single"],
62
  "author": ["org_country_single", "author", "merged_country_groups_single"],
63
+ "model": [
64
+ "org_country_single",
65
+ "author",
66
+ "merged_country_groups_single",
67
+ "merged_modality",
68
+ "downloads",
69
+ ],
70
  }
71
 
72
+
73
  # Chip renderer
74
  def chip(text, bg_color="#F0F0F0"):
75
  return html.Span(
 
81
  "margin": "2px",
82
  "display": "inline-flex",
83
  "alignItems": "center",
84
+ "fontSize": "14px",
85
+ },
86
  )
87
 
88
+
89
  # Progress bar for % of total
90
+ def progress_bar(percent, bar_color="#082030"):
91
  return html.Div(
92
  style={
93
  "position": "relative",
 
119
  "fontSize": "12px",
120
  "lineHeight": "20px",
121
  "textAlign": "center",
122
+ },
123
+ ),
124
+ ],
125
  )
126
 
127
+
128
  # Helper to convert DataFrame to CSV and encode for download
129
  def df_to_download_link(df, filename):
130
  csv_string = df.to_csv(index=False)
 
133
  html.A(
134
  children=dmc.ActionIcon(
135
  DashIconify(icon="mdi:download", width=24),
136
+ size="lg",
137
+ color="#082030",
138
  ),
139
  id=f"download-{filename}",
140
  download=f"{filename}.csv",
141
  href=f"data:text/csv;base64,{b64}",
142
  target="_blank",
143
  title="Download CSV",
144
+ style={
145
+ "padding": "6px 12px",
146
+ "display": "inline-flex",
147
+ "alignItems": "center",
148
+ "justifyContent": "center",
149
+ },
150
  ),
151
+ style={"textAlign": "right"},
152
  )
153
 
154
+
155
  # Render multiple chips in one row
156
+ def render_chips(metadata_list, chip_color):
157
  chips = []
158
  for icon, name in metadata_list:
159
+ if isinstance(icon, str) and icon.endswith((".png", ".jpg", ".jpeg", ".svg")):
160
  chips.append(
161
+ html.Span(
162
+ [
163
+ html.Img(
164
+ src=icon, style={"height": "18px", "marginRight": "6px"}
165
+ ),
166
+ name,
167
+ ],
168
+ style={
169
+ "backgroundColor": chip_color,
170
+ "padding": "4px 10px",
171
+ "borderRadius": "12px",
172
+ "margin": "2px",
173
+ "display": "inline-flex",
174
+ "alignItems": "left",
175
+ "fontSize": "14px",
176
+ },
177
+ )
178
  )
179
  else:
180
  chips.append(chip(f"{icon} {name}", chip_color))
181
  return html.Div(
182
+ chips, style={"display": "flex", "flexWrap": "wrap", "justifyContent": "left"}
183
+ )
184
+
185
+
186
+ def render_table_content(
187
+ df, download_df, chip_color, bar_color="#082030", filename="data"
188
+ ):
189
+ return html.Div(
190
+ [
191
+ html.Table(
192
+ [
193
+ html.Thead(
194
+ html.Tr(
195
+ [
196
+ html.Th(
197
+ "Rank",
198
+ style={
199
+ "backgroundColor": "#F0F0F0",
200
+ "textAlign": "left",
201
+ },
202
+ ),
203
+ html.Th(
204
+ "Name",
205
+ style={
206
+ "backgroundColor": "#F0F0F0",
207
+ "textAlign": "left",
208
+ },
209
+ ),
210
+ html.Th(
211
+ "Metadata",
212
+ style={
213
+ "backgroundColor": "#F0F0F0",
214
+ "textAlign": "left",
215
+ "marginRight": "10px",
216
+ },
217
+ ),
218
+ html.Th(
219
+ "% of Total",
220
+ style={
221
+ "backgroundColor": "#F0F0F0",
222
+ "textAlign": "left",
223
+ },
224
+ ),
225
+ ]
226
+ )
227
+ ),
228
+ html.Tbody(
229
+ [
230
+ html.Tr(
231
+ [
232
+ html.Td(idx + 1, style={"textAlign": "center"}),
233
+ html.Td(row["Name"], style={"textAlign": "left"}),
234
+ html.Td(render_chips(row["Metadata"], chip_color)),
235
+ html.Td(
236
+ progress_bar(row["% of total"], bar_color),
237
+ style={"textAlign": "center"},
238
+ ),
239
+ ]
240
+ )
241
+ for idx, row in df.iterrows()
242
+ ]
243
+ ),
244
+ ],
245
+ style={"borderCollapse": "collapse", "width": "100%"},
246
+ ),
247
+ ]
248
  )
249
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
250
 
251
  # Table renderer
252
+ def render_table(
253
+ df, download_df, title, chip_color, bar_color="#AC482A", filename="data"
254
+ ):
255
+ return html.Div(
256
+ id=f"{filename}-div",
257
+ children=[
258
+ html.Div(
259
+ [
260
+ html.H4(
261
+ title,
262
+ style={
263
+ "textAlign": "left",
264
+ "marginBottom": "10px",
265
+ "fontSize": "20px",
266
+ "display": "inline-block",
267
+ },
268
+ ),
269
+ df_to_download_link(download_df, filename),
270
+ ],
271
+ style={
272
+ "display": "flex",
273
+ "alignItems": "center",
274
+ "justifyContent": "space-between",
275
+ },
276
+ ),
277
+ html.Div(
278
+ id=f"{filename}-table",
279
+ children=[
280
+ html.Table(
281
+ [
282
+ html.Thead(
283
+ html.Tr(
284
+ [
285
+ html.Th(
286
+ "Rank",
287
+ style={
288
+ "backgroundColor": "#F0F0F0",
289
+ "textAlign": "left",
290
+ },
291
+ ),
292
+ html.Th(
293
+ "Name",
294
+ style={
295
+ "backgroundColor": "#F0F0F0",
296
+ "textAlign": "left",
297
+ },
298
+ ),
299
+ html.Th(
300
+ "Metadata",
301
+ style={
302
+ "backgroundColor": "#F0F0F0",
303
+ "textAlign": "left",
304
+ "marginRight": "10px",
305
+ },
306
+ ),
307
+ html.Th(
308
+ "% of Total",
309
+ style={
310
+ "backgroundColor": "#F0F0F0",
311
+ "textAlign": "left",
312
+ },
313
+ ),
314
+ ]
315
+ )
316
+ ),
317
+ html.Tbody(
318
+ [
319
+ html.Tr(
320
+ [
321
+ html.Td(
322
+ idx + 1, style={"textAlign": "center"}
323
+ ),
324
+ html.Td(
325
+ row["Name"], style={"textAlign": "left"}
326
+ ),
327
+ html.Td(
328
+ render_chips(
329
+ row["Metadata"], chip_color
330
+ )
331
+ ),
332
+ html.Td(
333
+ progress_bar(
334
+ row["% of total"], bar_color
335
+ ),
336
+ style={"textAlign": "center"},
337
+ ),
338
+ ]
339
+ )
340
+ for idx, row in df.iterrows()
341
+ ]
342
+ ),
343
+ ],
344
+ style={
345
+ "borderCollapse": "collapse",
346
+ "width": "100%",
347
+ "border": "none",
348
+ },
349
+ ),
350
+ ],
351
+ ),
352
+ dcc.Loading(
353
+ id=f"loading-{filename}-toggle",
354
+ type="dot",
355
+ color="#082030",
356
+ children=html.Div(
357
+ [
358
+ html.Button(
359
+ "▼ Show Top 50",
360
+ id=f"{filename}-toggle",
361
+ n_clicks=0,
362
+ style={**button_style, "border": "none"},
363
+ )
364
+ ],
365
+ style={"marginTop": "5px", "textAlign": "left"},
366
+ ),
367
+ ),
368
+ ],
369
+ style={"marginBottom": "20px"},
370
+ )
371
+
372
 
373
  # Function to get top N leaderboard
374
  def get_top_n_leaderboard(filtered_df, group_col, top_n=10):
375
+ top = (
376
+ filtered_df.groupby(group_col)["downloads"]
377
+ .sum()
378
+ .nlargest(top_n)
379
+ .reset_index()
380
+ .rename(columns={group_col: "Name", "downloads": "Total Value"})
381
+ )
382
  total_value = top["Total Value"].sum()
383
  top["% of total"] = top["Total Value"] / total_value * 100 if total_value else 0
384
 
 
403
  unique_vals = name_data[col].unique()
404
  meta_map[name][col] = list(unique_vals)
405
  download_map[name][col] = list(unique_vals)
406
+
407
  # Function to build metadata chips
408
  def build_metadata(nm):
409
  meta = meta_map.get(nm, {})
 
426
  chips.append((icon, a))
427
  # Downloads
428
  # Sum downloads if multiple entries
429
+ total_downloads = sum(
430
+ d for d in meta.get("downloads", []) if pd.notna(d)
431
+ ) # Check if d is not NaN
432
  if total_downloads:
433
  chips.append(("⬇️", f"{int(total_downloads):,}"))
434
 
435
  # Modality
436
  for m in meta.get("merged_modality", []):
437
  chips.append(("", m))
438
+
439
  # Estimated Parameters
440
  for p in meta.get("estimated_parameters", []):
441
  if pd.notna(p): # Check if p is not NaN
442
  if p >= 1e9:
443
+ p_str = f"{p / 1e9:.1f}B"
444
  elif p >= 1e6:
445
+ p_str = f"{p / 1e6:.1f}M"
446
  elif p >= 1e3:
447
+ p_str = f"{p / 1e3:.1f}K"
448
  else:
449
  p_str = str(p)
450
  chips.append(("⚙️", p_str))
451
  return chips
452
+
453
  # Function to create downloadable dataframe
454
  def build_download_metadata(nm):
455
  meta = download_map.get(nm, {})
 
465
  else:
466
  download_info[col] = ""
467
  return download_info
468
+
469
  # Apply metadata builder to top dataframe
470
  top["Metadata"] = top["Name"].astype(object).apply(build_metadata)
471
  download_info_list = [build_download_metadata(nm) for nm in download_top["Name"]]
 
474
 
475
  return top[["Name", "Metadata", "% of total"]], download_top
476
 
 
 
 
 
477
 
478
+ def create_leaderboard(filtered_df, board_type, top_n=10):
479
  if filtered_df.empty:
480
  return html.Div("No data in selected range")
481
+
482
  # Merge HF and USA
483
+ filtered_df["org_country_single"] = filtered_df["org_country_single"].replace(
484
+ {"HF": "United States of America"}
485
+ )
486
  # Merge International and Online
487
+ filtered_df["org_country_single"] = filtered_df["org_country_single"].replace(
488
+ {"International": "International/Online", "Online": "International/Online"}
489
+ )
490
 
491
  # Build leaderboards
492
+ top_countries, download_top_countries = get_top_n_leaderboard(
493
+ filtered_df, "org_country_single", top_n
494
+ )
495
+ top_developers, download_top_developers = get_top_n_leaderboard(
496
+ filtered_df, "author", top_n
497
+ )
498
  top_models, download_top_models = get_top_n_leaderboard(filtered_df, "model", top_n)
499
 
500
  if board_type == "countries":
501
+ return render_table(
502
+ top_countries,
503
+ download_top_countries,
504
+ "Top Countries",
505
+ chip_color="#F0F9FF",
506
+ bar_color="#082030",
507
+ filename="top_countries",
508
+ )
509
  elif board_type == "developers":
510
+ return render_table(
511
+ top_developers,
512
+ download_top_developers,
513
+ "Top Developers",
514
+ chip_color="#F0F9FF",
515
+ bar_color="#082030",
516
+ filename="top_developers",
517
+ )
518
  else:
519
+ return render_table(
520
+ top_models,
521
+ download_top_models,
522
+ "Top Models",
523
+ chip_color="#F0F9FF",
524
+ bar_color="#082030",
525
+ filename="top_models",
526
+ )