emsesc commited on
Commit
ceae916
·
1 Parent(s): 867111e

leaderboard

Browse files
app.py CHANGED
@@ -1,332 +1,477 @@
1
- import dash
 
2
  import dash_mantine_components as dmc
3
- import plotly.express as px
4
- from dash import Input, Output, callback, dcc, html
5
- from dash_iconify import DashIconify
6
-
 
7
 
8
- app = dash.Dash(__name__)
 
9
  server = app.server
10
 
11
- df = px.data.gapminder()
12
-
13
-
14
- def create_scatter_plot(selected_year, selected_continent=None):
15
- filtered_df = df[df["year"] == selected_year]
16
-
17
- if selected_continent and selected_continent != "All":
18
- filtered_df = filtered_df[filtered_df["continent"] == selected_continent]
19
-
20
- fig = px.scatter(
21
- filtered_df,
22
- x="gdpPercap",
23
- y="lifeExp",
24
- size="pop",
25
- color="continent",
26
- hover_name="country",
27
- log_x=True,
28
- size_max=60,
29
- title=f"Life Expectancy vs GDP per Capita ({selected_year})",
30
- )
31
-
32
- fig.update_layout(
33
- template="plotly_dark",
34
- paper_bgcolor="rgba(0,0,0,0)",
35
- plot_bgcolor="rgba(0,0,0,0)",
36
- )
37
-
38
- return fig
39
 
 
 
40
 
41
- def create_line_chart(selected_country):
42
- country_data = df[df["country"] == selected_country]
43
- fig = px.line(
44
- country_data,
45
- x="year",
46
- y="lifeExp",
47
- title=f"{selected_country} - Life Expectancy",
48
- )
49
- fig.update_layout(
50
- template="plotly_dark",
51
- paper_bgcolor="rgba(0,0,0,0)",
52
- plot_bgcolor="rgba(0,0,0,0)",
53
- )
54
- return fig
55
 
 
 
 
 
 
 
 
 
 
 
 
56
 
57
- def create_bar_chart(selected_year):
58
- year_data = df[df["year"] == selected_year]
59
- continent_stats = year_data.groupby("continent")["lifeExp"].mean().reset_index()
60
- fig = px.bar(
61
- continent_stats,
62
- x="continent",
63
- y="lifeExp",
64
- color="continent",
65
- title=f"Average Life Expectancy by Continent ({selected_year})",
66
- )
67
- fig.update_layout(
68
- template="plotly_dark",
69
- paper_bgcolor="rgba(0,0,0,0)",
70
- plot_bgcolor="rgba(0,0,0,0)",
71
- showlegend=False,
72
- )
73
- return fig
74
-
75
-
76
- def create_datacard(title, value, icon, color):
77
- return dmc.Card(
78
- [
79
- dmc.Group(
80
- [
81
- DashIconify(icon=icon, width=30, color=color),
82
- html.Div(
83
- [
84
- dmc.Text(value, size="xl", fw=700, c="white"),
85
- dmc.Text(title, size="sm", c="dimmed"),
86
- ]
87
- ),
88
- ],
89
- align="center",
90
- gap="md",
91
- )
92
- ],
93
- p="md",
94
- className="datacard",
95
- )
96
-
97
 
 
98
  app.layout = dmc.MantineProvider(
99
- [
100
- html.Link(
101
- href="https://fonts.googleapis.com/css2?family=Outfit:wght@100..900&display=swap",
102
- rel="stylesheet",
103
- ),
104
- dmc.Group(
105
- [
106
- DashIconify(icon="twemoji:globe-with-meridians", width=45),
107
- dmc.Text(
108
- "Gapminder World Data Explorer", ml=10, size="xl", fw=900, c="white"
109
- ),
110
- ],
111
- align="center",
112
- className="header",
113
- mb="md",
114
- ),
115
- dmc.Grid(
116
  [
117
- dmc.GridCol(
 
118
  [
119
- dmc.Stack(
120
  [
121
- dmc.Card(
122
  [
123
- dmc.Text("Controls", size="lg", mb="md"),
124
- dmc.Stack(
125
- [
126
- html.Div(
127
- [
128
- dmc.Text(
129
- "Year:", size="sm", mb=5
130
- ),
131
- dmc.Slider(
132
- id="year-slider",
133
- min=1952,
134
- max=2007,
135
- step=5,
136
- value=2007,
137
- marks=[
138
- {
139
- "value": year,
140
- "label": str(year),
141
- }
142
- for year in [
143
- 1952,
144
- 1967,
145
- 1982,
146
- 1997,
147
- 2007,
148
- ]
149
- ],
150
- ),
151
- ]
152
- ),
153
- html.Div(
154
- [
155
- dmc.Text(
156
- "Continent Filter:",
157
- size="sm",
158
- mb=5,
159
- ),
160
- dmc.Select(
161
- id="continent-dropdown",
162
- data=[
163
- {
164
- "value": "All",
165
- "label": "All Continents",
166
- }
167
- ]
168
- + [
169
- {
170
- "value": cont,
171
- "label": cont,
172
- }
173
- for cont in sorted(
174
- df[
175
- "continent"
176
- ].unique()
177
- )
178
- ],
179
- value="All",
180
- ),
181
- ]
182
- ),
183
- html.Div(
184
- [
185
- dmc.Text(
186
- "Select Country:",
187
- size="sm",
188
- mb=5,
189
- ),
190
- dmc.Select(
191
- id="country-dropdown",
192
- data=[
193
- {
194
- "value": country,
195
- "label": country,
196
- }
197
- for country in sorted(
198
- df[
199
- "country"
200
- ].unique()
201
- )
202
- ],
203
- value="United States",
204
- searchable=True,
205
- ),
206
- ]
207
  ),
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
208
  ],
209
- gap="lg",
 
 
 
 
 
 
 
 
 
210
  ),
211
  ],
212
- p="md",
213
- className="control-card",
214
- )
215
- ]
216
- )
 
 
 
 
 
 
 
 
217
  ],
218
- span=3,
 
 
 
 
219
  ),
220
- dmc.GridCol(
221
- [
222
- dmc.Stack(
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
223
  [
224
- html.Div(id="stats-cards"),
225
- dmc.Card(
226
- [dcc.Graph(id="scatter-plot")],
227
- p="sm",
228
- className="chart-card",
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
229
  ),
230
  ],
231
- gap="md",
232
- )
233
- ],
234
- span=9,
235
- ),
236
- ],
237
- gutter="md",
238
- ),
239
- dmc.Grid(
240
- [
241
- dmc.GridCol(
242
- [
243
- dmc.Card(
244
- [dcc.Graph(id="line-chart")], p="sm", className="chart-card"
245
- )
 
246
  ],
247
- span=6,
 
 
 
 
 
 
 
 
 
 
248
  ),
249
- dmc.GridCol(
250
  [
251
- dmc.Card(
252
- [dcc.Graph(id="bar-chart")], p="sm", className="chart-card"
253
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
254
  ],
255
- span=6,
 
 
 
 
 
 
 
 
256
  ),
257
  ],
258
- gutter="md",
259
- mt="md",
260
- ),
 
 
 
261
  ],
262
- forceColorScheme="dark",
263
- theme={"colorScheme": "dark"},
264
  )
265
 
 
 
 
 
 
 
 
 
266
 
267
- @callback(
268
- Output("scatter-plot", "figure"),
269
- [Input("year-slider", "value"), Input("continent-dropdown", "value")],
270
- )
271
- def update_scatter_plot(selected_year, selected_continent):
272
- return create_scatter_plot(selected_year, selected_continent)
273
-
274
 
275
- @callback(Output("line-chart", "figure"), Input("country-dropdown", "value"))
276
- def update_line_chart(selected_country):
277
- return create_line_chart(selected_country)
 
 
 
 
 
 
 
278
 
 
 
 
 
 
279
 
280
- @callback(Output("bar-chart", "figure"), Input("year-slider", "value"))
281
- def update_bar_chart(selected_year):
282
- return create_bar_chart(selected_year)
283
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
284
 
285
- @callback(Output("stats-cards", "children"), Input("year-slider", "value"))
286
- def update_stats(selected_year):
287
- year_data = df[df["year"] == selected_year]
288
-
289
- avg_life_exp = round(year_data["lifeExp"].mean(), 1)
290
- total_pop = year_data["pop"].sum()
291
- num_countries = len(year_data)
292
- avg_gdp = round(year_data["gdpPercap"].mean(), 0)
 
 
 
 
 
 
 
 
 
293
 
294
- return dmc.Grid(
295
- [
296
- dmc.GridCol(
297
- create_datacard(
298
- "Life Expectancy",
299
- f"{avg_life_exp} years",
300
- "mdi:heart-pulse",
301
- "#ff6b35",
302
- ),
303
- span=3,
304
- ),
305
- dmc.GridCol(
306
- create_datacard(
307
- "Population",
308
- f"{total_pop / 1e9:.1f}B",
309
- "mdi:account-group",
310
- "#1f77b4",
311
- ),
312
- span=3,
313
- ),
314
- dmc.GridCol(
315
- create_datacard(
316
- "Countries", str(num_countries), "mdi:earth", "#2ca02c"
317
- ),
318
- span=3,
319
- ),
320
- dmc.GridCol(
321
- create_datacard(
322
- "GDP per Capita", f"${avg_gdp:,.0f}", "mdi:currency-usd", "#d62728"
323
- ),
324
- span=3,
325
- ),
326
- ],
327
- gutter="sm",
328
  )
329
 
 
 
 
 
 
 
 
 
 
330
 
 
331
  if __name__ == "__main__":
332
- app.run(debug=True, port=8050)
 
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()
12
  server = app.server
13
 
14
+ # Load parquet file from Hugging Face
15
+ print("Loading data...")
16
+ hf_parquet_url = "https://huggingface.co/datasets/emsesc/open_model_evolution_data/resolve/main/filtered_df.parquet"
17
+ filtered_df = pd.read_parquet(hf_parquet_url)
18
+ print("Data loaded.")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
 
20
+ # List columns for reference
21
+ print(filtered_df.columns.tolist())
22
 
23
+ # Create a dcc slider for time range selection by year (readable marks)
24
+ start_dt = filtered_df["time"].min()
25
+ end_dt = filtered_df["time"].max()
26
+ start_ts = int(start_dt.timestamp())
27
+ end_ts = int(end_dt.timestamp())
 
 
 
 
 
 
 
 
 
28
 
29
+ marks = []
30
+ # Add start label (e.g. "Jan 2020")
31
+ marks.append({"value": start_ts, "label": start_dt.strftime("%b %Y")})
32
+ # Add yearly marks between start and end (e.g. "2021", "2022")
33
+ for yr in range(start_dt.year, end_dt.year + 1):
34
+ yr_ts = int(pd.Timestamp(year=yr, month=1, day=1).timestamp())
35
+ start_yr = int(pd.Timestamp(year=start_dt.year, month=1, day=1).timestamp())
36
+ if yr_ts != start_yr and yr_ts != end_ts:
37
+ marks.append({"value": yr_ts, "label": str(yr)})
38
+ # Add end label (e.g. "Dec 2024")
39
+ marks.append({"value": end_ts, "label": end_dt.strftime("%b %Y")})
40
 
41
+ # Create a dcc slider for time range selection by year
42
+ time_slider = dmc.RangeSlider(
43
+ id="time-slider",
44
+ min=start_ts,
45
+ max=end_ts,
46
+ value=[
47
+ start_ts,
48
+ end_ts,
49
+ ],
50
+ step=24 * 60 * 60,
51
+ color="#AC482A",
52
+ size="md",
53
+ radius="xl",
54
+ marks=marks,
55
+ style={"width": "70%", "margin": "0 auto"},
56
+ labelAlwaysOn=False,
57
+ # thumbChildren=[
58
+ # dmc.Text(id="time-slider-thumb-from-label", size="xs", children="Hello"),
59
+ # dmc.Text(id="time-slider-thumb-to-label", size="xs"),
60
+ # ]
61
+ )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
62
 
63
+ # App layout
64
  app.layout = dmc.MantineProvider(
65
+ theme={
66
+ "colorScheme": "light",
67
+ "primaryColor": "blue",
68
+ "fontFamily": "Inter, sans-serif",
69
+ },
70
+ children=[
71
+ html.Div(
 
 
 
 
 
 
 
 
 
 
72
  [
73
+ # Header
74
+ html.Div(
75
  [
76
+ html.Div(
77
  [
78
+ html.Div(
79
  [
80
+ html.Div(
81
+ children="Visualizing the Open Model Ecosystem",
82
+ style={
83
+ "fontSize": 22,
84
+ "fontWeight": "700",
85
+ "lineHeight": "1.1",
86
+ },
87
+ ),
88
+ html.Div(
89
+ children="An interactive dashboard to explore trends in open models on Hugging Face",
90
+ style={
91
+ "fontSize": 13,
92
+ "marginTop": 6,
93
+ "opacity": 0.9,
94
+ },
95
+ ),
96
+ ],
97
+ style={
98
+ "display": "flex",
99
+ "flexDirection": "column",
100
+ "justifyContent": "center",
101
+ },
102
+ ),
103
+ html.Div(
104
+ [
105
+ html.A(
106
+ children=[
107
+ html.Img(
108
+ src="assets/images/dpi-logo.svg",
109
+ style={
110
+ "height": "28px",
111
+ "verticalAlign": "middle",
112
+ "paddingRight": "8px",
113
+ },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
114
  ),
115
+ "Data Provenance Initiative",
116
+ ],
117
+ href="https://www.dataprovenance.org/",
118
+ target="_blank",
119
+ style={
120
+ "display": "inline-block",
121
+ "padding": "6px 14px",
122
+ "fontSize": 13,
123
+ "color": "#082030",
124
+ "backgroundColor": "#ffffff",
125
+ "borderRadius": "18px",
126
+ "fontWeight": "700",
127
+ "textDecoration": "none",
128
+ "marginRight": "12px",
129
+ },
130
+ ),
131
+ html.A(
132
+ children=[
133
+ html.Img(
134
+ src="assets/images/Hf-logo-with-title.svg",
135
+ style={
136
+ "height": "30px",
137
+ "verticalAlign": "middle",
138
+ },
139
+ )
140
  ],
141
+ href="https://huggingface.co/",
142
+ target="_blank",
143
+ style={
144
+ "display": "inline-flex",
145
+ "padding": "6px 14px",
146
+ "alignItems": "center",
147
+ "backgroundColor": "#ffffff",
148
+ "borderRadius": "18px",
149
+ "textDecoration": "none",
150
+ },
151
  ),
152
  ],
153
+ style={"display": "flex", "alignItems": "center"},
154
+ ),
155
+ ],
156
+ style={
157
+ "marginLeft": "50px",
158
+ "marginRight": "50px",
159
+ "display": "flex",
160
+ "justifyContent": "space-between",
161
+ "alignItems": "center",
162
+ "padding": "18px 24px",
163
+ "gap": "24px",
164
+ },
165
+ ),
166
  ],
167
+ style={
168
+ "backgroundColor": "#082030",
169
+ "color": "white",
170
+ "width": "100%",
171
+ },
172
  ),
173
+ # Intro / description below header (kept but styled to match layout)
174
+ # Title
175
+ html.Div(
176
+ children="Model Leaderboard", # Change this to your desired title
177
+ style={
178
+ "fontSize": 40,
179
+ "fontWeight": "700",
180
+ "textAlign": "center",
181
+ "marginTop": 20,
182
+ "marginBottom": 20,
183
+ },
184
+ ),
185
+ # Button
186
+ html.Div(
187
+ children=[
188
+ html.Button(
189
+ "Read the paper", # Change this to your desired button text
190
+ id="my-button",
191
+ style={
192
+ "padding": "10px 20px",
193
+ "fontSize": 16,
194
+ "margin": "0 auto",
195
+ "display": "block",
196
+ "backgroundColor": "#AC482A",
197
+ "color": "white",
198
+ "border": "none",
199
+ "borderRadius": "5px",
200
+ "cursor": "pointer",
201
+ },
202
+ ),
203
+ ],
204
+ style={"textAlign": "center", "marginBottom": 20},
205
+ ),
206
+ html.Div(
207
+ 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...",
208
+ style={
209
+ "fontSize": 14,
210
+ "marginTop": 18,
211
+ "marginBottom": 12,
212
+ "marginLeft": 100,
213
+ "marginRight": 100,
214
+ "textAlign": "center",
215
+ },
216
+ ),
217
+ # Main content (filters + tabs)
218
+ html.Div(
219
+ children=[
220
+ html.Div(
221
  [
222
+ html.Div(
223
+ "Select Window",
224
+ style={
225
+ "fontWeight": "700",
226
+ "marginBottom": 8,
227
+ "fontSize": 14,
228
+ },
229
+ ),
230
+ dmc.SegmentedControl(
231
+ id="segmented",
232
+ value="all-downloads",
233
+ color="#AC482A",
234
+ transitionDuration=200,
235
+ data=[
236
+ {
237
+ "value": "all-downloads",
238
+ "label": "All Downloads",
239
+ },
240
+ {
241
+ "value": "filtered-downloads",
242
+ "label": "Filtered Downloads",
243
+ },
244
+ ],
245
+ mb=10,
246
+ ),
247
+ html.Span(
248
+ id="global-toggle-status",
249
+ style={
250
+ "marginLeft": "8px",
251
+ "display": "inline-block",
252
+ "marginTop": 6,
253
+ },
254
  ),
255
  ],
256
+ style={"flex": 1, "minWidth": "220px"},
257
+ ),
258
+ html.Div(
259
+ [
260
+ html.Div(
261
+ "Select Time Range",
262
+ style={
263
+ "fontWeight": "700",
264
+ "marginBottom": 8,
265
+ "fontSize": 14,
266
+ },
267
+ ),
268
+ time_slider,
269
+ ],
270
+ style={"flex": 2, "minWidth": "320px"},
271
+ ),
272
  ],
273
+ style={
274
+ "display": "flex",
275
+ "gap": "24px",
276
+ "padding": "32px",
277
+ "alignItems": "flex-start",
278
+ # 'margin': '24px auto 64px', # centered horizontally
279
+ "marginLeft": "100px",
280
+ "marginRight": "100px",
281
+ "backgroundColor": "#FFFBF9",
282
+ "borderRadius": "18px",
283
+ },
284
  ),
285
+ html.Div(
286
  [
287
+ dcc.Tabs(
288
+ id="leaderboard-tabs",
289
+ value="Countries",
290
+ children=[ # wrap Tabs here
291
+ dcc.Tab(
292
+ label="Countries",
293
+ value="Countries",
294
+ style={
295
+ "backgroundColor": "transparent",
296
+ "border": "none",
297
+ "padding": "10px 18px",
298
+ "color": "#6B7280",
299
+ "fontWeight": "500",
300
+ },
301
+ selected_style={
302
+ "backgroundColor": "transparent",
303
+ "border": "none",
304
+ "padding": "10px 18px",
305
+ "fontWeight": "700",
306
+ "borderBottom": "3px solid #082030", # underline only
307
+ },
308
+ children=[
309
+ create_leaderboard(filtered_df, "countries")
310
+ ],
311
+ ),
312
+ dcc.Tab(
313
+ label="Developers",
314
+ value="Developers",
315
+ style={
316
+ "backgroundColor": "transparent",
317
+ "border": "none",
318
+ "padding": "10px 18px",
319
+ "color": "#6B7280",
320
+ "fontWeight": "500",
321
+ },
322
+ selected_style={
323
+ "backgroundColor": "transparent",
324
+ "border": "none",
325
+ "padding": "10px 18px",
326
+ "fontWeight": "700",
327
+ "borderBottom": "3px solid #082030",
328
+ },
329
+ children=[
330
+ create_leaderboard(filtered_df, "developers")
331
+ ],
332
+ ),
333
+ dcc.Tab(
334
+ label="Models",
335
+ value="Models",
336
+ style={
337
+ "backgroundColor": "transparent",
338
+ "border": "none",
339
+ "padding": "10px 18px",
340
+ "color": "#6B7280",
341
+ "fontWeight": "500",
342
+ },
343
+ selected_style={
344
+ "backgroundColor": "transparent",
345
+ "border": "none",
346
+ "padding": "10px 18px",
347
+ "fontWeight": "700",
348
+ "borderBottom": "3px solid #082030",
349
+ },
350
+ children=[
351
+ create_leaderboard(filtered_df, "models")
352
+ ],
353
+ ),
354
+ ],
355
+ ),
356
  ],
357
+ style={
358
+ "borderRadius": "18px",
359
+ "padding": "32px",
360
+ "marginTop": "12px",
361
+ "marginBottom": "64px",
362
+ "marginLeft": "50px",
363
+ "marginRight": "50px",
364
+ # 'maxWidth': '1250px',
365
+ },
366
  ),
367
  ],
368
+ style={
369
+ "fontFamily": "Inter",
370
+ "backgroundColor": "#ffffff",
371
+ "minHeight": "100vh",
372
+ },
373
+ )
374
  ],
 
 
375
  )
376
 
377
+ # Callbacks for interactivity
378
+ # -- helper utilities to consolidate duplicated callback logic --
379
+ def _apply_time_slider(slider_value):
380
+ if slider_value and len(slider_value) == 2:
381
+ start = pd.to_datetime(slider_value[0], unit="s")
382
+ end = pd.to_datetime(slider_value[1], unit="s")
383
+ return filtered_df[(filtered_df["time"] >= start) & (filtered_df["time"] <= end)]
384
+ return filtered_df
385
 
386
+ def _leaderboard_callback_logic(n_clicks, slider_value, current_label, group_col, filename, default_label="▼ Show Top 50", chip_color="#F0F9FF"):
387
+ # Normalize label on first load
388
+ if current_label is None:
389
+ current_label = default_label
 
 
 
390
 
391
+ # Determine top_n and next label
392
+ if n_clicks == 0:
393
+ top_n = 10
394
+ new_label = current_label
395
+ elif "Show Top 50" in current_label:
396
+ top_n, new_label = 50, "▼ Show Top 100"
397
+ elif "Show Top 100" in current_label:
398
+ top_n, new_label = 100, "▲ Show Less"
399
+ else:
400
+ top_n, new_label = 10, "▼ Show Top 50"
401
 
402
+ # Apply time filter and build table
403
+ df_time = _apply_time_slider(slider_value)
404
+ df, download_df = get_top_n_leaderboard(df_time, group_col, top_n)
405
+ return render_table_content(df, download_df, chip_color=chip_color, filename=filename), new_label
406
+ # -- end helpers --
407
 
408
+ # ...existing code...
 
 
409
 
410
+ # Callbacks for interactivity (modularized)
411
+ @app.callback(
412
+ Output("top_countries-table", "children"),
413
+ Output("top_countries-toggle", "children"),
414
+ Input("top_countries-toggle", "n_clicks"),
415
+ Input("time-slider", "value"),
416
+ State("top_countries-toggle", "children"),
417
+ )
418
+ def update_top_countries(n_clicks, slider_value, current_label):
419
+ return _leaderboard_callback_logic(
420
+ n_clicks,
421
+ slider_value,
422
+ current_label,
423
+ group_col="org_country_single",
424
+ filename="top_countries",
425
+ default_label="▼ Show Top 50",
426
+ chip_color="#F0F9FF",
427
+ )
428
 
429
+ @app.callback(
430
+ Output("top_developers-table", "children"),
431
+ Output("top_developers-toggle", "children"),
432
+ Input("top_developers-toggle", "n_clicks"),
433
+ Input("time-slider", "value"),
434
+ State("top_developers-toggle", "children"),
435
+ )
436
+ def update_top_developers(n_clicks, slider_value, current_label):
437
+ return _leaderboard_callback_logic(
438
+ n_clicks,
439
+ slider_value,
440
+ current_label,
441
+ group_col="author",
442
+ filename="top_developers",
443
+ default_label="▼ Show More",
444
+ chip_color="#F0F9FF",
445
+ )
446
 
447
+ @app.callback(
448
+ Output("top_models-table", "children"),
449
+ Output("top_models-toggle", "children"),
450
+ Input("top_models-toggle", "n_clicks"),
451
+ Input("time-slider", "value"),
452
+ State("top_models-toggle", "children"),
453
+ )
454
+ def update_top_models(n_clicks, slider_value, current_label):
455
+ return _leaderboard_callback_logic(
456
+ n_clicks,
457
+ slider_value,
458
+ current_label,
459
+ group_col="model",
460
+ filename="top_models",
461
+ default_label=" Show More",
462
+ chip_color="#F0F9FF",
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
463
  )
464
 
465
+ @app.callback(
466
+ Output("time-slider", "label"),
467
+ Input("time-slider", "value")
468
+ )
469
+ def update_range_labels(values):
470
+ start_label = pd.to_datetime(values[0], unit="s").strftime("%b %Y")
471
+ end_label = pd.to_datetime(values[1], unit="s").strftime("%b %Y")
472
+ return [start_label, end_label]
473
+
474
 
475
+ # Run the app
476
  if __name__ == "__main__":
477
+ app.run(debug=True)
assets/icons/google.png ADDED

Git LFS Details

  • SHA256: d65d89c2be2ccf3b76f0a1bc302c2a578805b39424f981fa54830766032fedb0
  • Pointer size: 130 Bytes
  • Size of remote file: 20.9 kB
assets/icons/meta.png ADDED

Git LFS Details

  • SHA256: e93526c7b5c3f823dabd5f62ff3b5a37260ddf73df3e2ecaeeec003e40f34b76
  • Pointer size: 130 Bytes
  • Size of remote file: 26.3 kB
assets/icons/openai.png ADDED

Git LFS Details

  • SHA256: a8a35e0bbaa9171dcd64937c39aeb6fa4acfcf0b76a0830e341f2e96a5ef69f3
  • Pointer size: 130 Bytes
  • Size of remote file: 23.9 kB
assets/images/Hf-logo-with-title.svg ADDED
assets/images/dpi-logo.svg ADDED
assets/styles.css DELETED
@@ -1,107 +0,0 @@
1
- body {
2
- font-family: 'Outfit', sans-serif;
3
- background: linear-gradient(135deg, #1e1e2e 0%, #2a2a3e 100%);
4
- margin: 0;
5
- padding: 20px;
6
- min-height: 100vh;
7
- }
8
-
9
- .header {
10
- background: linear-gradient(135deg, #ff6b35, #d43425);
11
- padding: 20px 30px;
12
- border-radius: 15px;
13
- box-shadow: 0 8px 25px rgba(255, 107, 53, 0.3);
14
- margin-bottom: 20px;
15
- }
16
-
17
- .control-card {
18
- background: rgba(15, 15, 20, 0.9);
19
- border: 1px solid rgba(255, 255, 255, 0.1);
20
- backdrop-filter: blur(10px);
21
- border-radius: 15px;
22
- box-shadow: 0 8px 25px rgba(0, 0, 0, 0.3);
23
- }
24
-
25
- .chart-card {
26
- background: rgba(15, 15, 20, 0.9);
27
- border: 1px solid rgba(255, 255, 255, 0.1);
28
- backdrop-filter: blur(10px);
29
- border-radius: 15px;
30
- box-shadow: 0 8px 25px rgba(0, 0, 0, 0.3);
31
- }
32
-
33
- .datacard {
34
- background: linear-gradient(135deg, rgba(255, 107, 53, 0.1), rgba(212, 52, 37, 0.1));
35
- border: 1px solid rgba(255, 107, 53, 0.3);
36
- border-radius: 12px;
37
- transition: all 0.3s ease;
38
- backdrop-filter: blur(10px);
39
- }
40
-
41
- .datacard:hover {
42
- transform: translateY(-2px);
43
- box-shadow: 0 12px 30px rgba(255, 107, 53, 0.2);
44
- }
45
-
46
- .year-slider .mantine-Slider-track {
47
- background: rgba(255, 255, 255, 0.2);
48
- }
49
-
50
- .year-slider .mantine-Slider-bar {
51
- background: linear-gradient(90deg, #ff6b35, #d43425);
52
- }
53
-
54
- .year-slider .mantine-Slider-thumb {
55
- background: #ff6b35;
56
- border: 2px solid white;
57
- }
58
-
59
- .continent-select .mantine-Select-input,
60
- .country-select .mantine-Select-input {
61
- background: rgba(255, 255, 255, 0.1);
62
- border: 1px solid rgba(255, 255, 255, 0.2);
63
- color: white;
64
- }
65
-
66
- .continent-select .mantine-Select-input:focus,
67
- .country-select .mantine-Select-input:focus {
68
- border-color: #ff6b35;
69
- box-shadow: 0 0 10px rgba(255, 107, 53, 0.3);
70
- }
71
-
72
- /* Custom scrollbar for dropdowns */
73
- .mantine-Select-dropdown {
74
- background: rgba(15, 15, 20, 0.95);
75
- border: 1px solid rgba(255, 255, 255, 0.1);
76
- backdrop-filter: blur(10px);
77
- }
78
-
79
- .mantine-Select-item {
80
- color: white;
81
- }
82
-
83
- .mantine-Select-item:hover {
84
- background: rgba(255, 107, 53, 0.2);
85
- }
86
-
87
- /* Graph styling adjustments */
88
- .js-plotly-plot {
89
- border-radius: 10px;
90
- overflow: hidden;
91
- }
92
-
93
- /* Responsive design */
94
- @media (max-width: 768px) {
95
- body {
96
- padding: 10px;
97
- }
98
-
99
- .header {
100
- padding: 15px 20px;
101
- }
102
-
103
- .control-card,
104
- .chart-card {
105
- margin: 10px 0;
106
- }
107
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
graphs/leaderboard.py ADDED
@@ -0,0 +1,526 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import pandas as pd
2
+ from dash import html, dcc
3
+ from dash_iconify import DashIconify
4
+ 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": "#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",
54
+ "distilbert": "../assets/icons/hugging-face.png",
55
+ "sentence-transformers": "../assets/icons/hugging-face.png",
56
+ "facebook": "../assets/icons/meta.png",
57
+ "openai": "../assets/icons/openai.png",
58
+ }
59
+
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(
76
+ text,
77
+ style={
78
+ "backgroundColor": bg_color,
79
+ "padding": "4px 10px",
80
+ "borderRadius": "12px",
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",
94
+ "backgroundColor": "#E0E0E0",
95
+ "borderRadius": "8px",
96
+ "height": "20px",
97
+ "width": "100%",
98
+ "overflow": "hidden",
99
+ },
100
+ children=[
101
+ html.Div(
102
+ style={
103
+ "backgroundColor": bar_color,
104
+ "width": f"{percent}%",
105
+ "height": "100%",
106
+ "borderRadius": "8px",
107
+ "transition": "width 0.5s",
108
+ }
109
+ ),
110
+ html.Div(
111
+ f"{percent:.1f}%",
112
+ style={
113
+ "position": "absolute",
114
+ "top": 0,
115
+ "left": "50%",
116
+ "transform": "translateX(-50%)",
117
+ "color": "black",
118
+ "fontWeight": "bold",
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)
131
+ b64 = base64.b64encode(csv_string.encode()).decode()
132
+ return html.Div(
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
+
385
+ # Create a downloadable version of the leaderboard
386
+ download_top = top.copy()
387
+ download_top["Total Value"] = download_top["Total Value"].astype(int)
388
+ download_top["% of total"] = download_top["% of total"].round(2)
389
+
390
+ top["Name"].replace("User", "user")
391
+
392
+ # All relevant metadata columns
393
+ meta_cols = meta_cols_map.get(group_col, [])
394
+ # Collect all metadata per top n for each category (country, author, model)
395
+ meta_map = {}
396
+ download_map = {}
397
+ for name in top["Name"]:
398
+ name_data = filtered_df[filtered_df[group_col] == name]
399
+ meta_map[name] = {}
400
+ download_map[name] = {}
401
+ for col in meta_cols:
402
+ if col in name_data.columns:
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, {})
410
+ chips = []
411
+ # Countries
412
+ for c in meta.get("org_country_single", []):
413
+ if c == "United States of America":
414
+ c = "USA"
415
+ if c == "user":
416
+ c = "User"
417
+ chips.append((country_icon_map.get(c, ""), c))
418
+ # Author
419
+ for a in meta.get("author", []):
420
+ icon = company_icon_map.get(a, "")
421
+ if icon == "":
422
+ if meta.get("merged_country_groups_single", ["User"])[0] != "User":
423
+ icon = "🏢"
424
+ else:
425
+ icon = "👤"
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, {})
456
+ download_info = {}
457
+ for col in meta_cols:
458
+ # don't add empty columns
459
+ if col not in meta or not meta[col]:
460
+ continue
461
+ vals = meta.get(col, [])
462
+ if vals:
463
+ # Join list into a single string for CSV
464
+ download_info[col] = ", ".join(str(v) for v in vals)
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"]]
472
+ download_info_df = pd.DataFrame(download_info_list)
473
+ download_top = pd.concat([download_top, download_info_df], axis=1)
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
+ )
requirements.txt CHANGED
@@ -1,6 +1,7 @@
 
1
  dash
2
- dash-mantine-components
3
- dash-iconify
4
  plotly
5
- pandas
6
- gunicorn
 
 
 
1
+ pandas
2
  dash
 
 
3
  plotly
4
+ gunicorn
5
+ dash-mantine-components
6
+ dash-bootstrap-components
7
+ pyarrow