redo leaderboard
Browse files- app.py +409 -169
- assets/images/Hf-logo-with-title.svg +9 -0
- assets/images/dpi-logo.svg +3 -0
- graphs/leaderboard.py +327 -141
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
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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 |
-
|
| 15 |
-
id=
|
| 16 |
-
min=
|
| 17 |
-
max=
|
| 18 |
-
|
| 19 |
-
|
| 20 |
-
|
| 21 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 22 |
)
|
| 23 |
|
| 24 |
# App layout
|
| 25 |
app.layout = dmc.MantineProvider(
|
| 26 |
-
theme={
|
| 27 |
-
|
| 28 |
-
|
| 29 |
-
|
| 30 |
-
|
|
|
|
| 31 |
html.Div(
|
| 32 |
[
|
| 33 |
-
|
| 34 |
-
html.Div(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 35 |
html.Div(
|
| 36 |
children=[
|
| 37 |
-
html.
|
| 38 |
-
"
|
| 39 |
-
|
| 40 |
-
target="_blank",
|
| 41 |
style={
|
| 42 |
-
|
| 43 |
-
|
| 44 |
-
|
| 45 |
-
|
| 46 |
-
|
| 47 |
-
|
| 48 |
-
|
| 49 |
-
|
| 50 |
-
|
| 51 |
-
|
| 52 |
-
|
| 53 |
-
'marginBottom': '4px',
|
| 54 |
-
'transition': 'background 0.2s',
|
| 55 |
-
'cursor': 'pointer'
|
| 56 |
-
}
|
| 57 |
-
)
|
| 58 |
],
|
| 59 |
-
style={
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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 |
-
|
| 112 |
-
|
| 113 |
-
|
| 114 |
-
|
| 115 |
-
'margin': '32px auto',
|
| 116 |
-
'maxWidth': '1250px',
|
| 117 |
-
}
|
| 118 |
)
|
| 119 |
],
|
| 120 |
-
|
| 121 |
-
)])
|
| 122 |
|
| 123 |
# Callbacks for interactivity
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 124 |
|
| 125 |
-
|
| 126 |
-
#
|
| 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 =
|
| 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 |
-
|
| 178 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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 |
-
|
| 189 |
-
|
| 190 |
-
|
| 191 |
-
|
| 192 |
-
|
| 193 |
-
|
| 194 |
-
|
| 195 |
-
|
| 196 |
-
|
| 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 |
-
|
| 213 |
-
|
| 214 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 215 |
|
| 216 |
-
|
| 217 |
-
|
| 218 |
-
|
| 219 |
-
|
| 220 |
-
|
| 221 |
-
|
| 222 |
-
|
| 223 |
-
|
| 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__ ==
|
| 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 |
-
|
| 9 |
-
|
| 10 |
-
|
| 11 |
-
|
| 12 |
-
|
| 13 |
-
|
| 14 |
-
|
| 15 |
-
|
| 16 |
-
|
| 17 |
-
|
| 18 |
-
|
| 19 |
-
|
| 20 |
|
| 21 |
country_icon_map = {
|
| 22 |
-
|
| 23 |
-
|
| 24 |
-
|
| 25 |
-
|
| 26 |
-
|
| 27 |
-
|
| 28 |
-
|
| 29 |
-
|
| 30 |
-
|
| 31 |
-
|
| 32 |
-
|
| 33 |
-
|
| 34 |
-
|
| 35 |
-
|
| 36 |
-
|
| 37 |
-
|
| 38 |
-
|
| 39 |
-
|
| 40 |
-
|
| 41 |
-
|
| 42 |
-
|
| 43 |
-
|
| 44 |
-
|
| 45 |
-
|
| 46 |
-
|
| 47 |
-
|
| 48 |
-
|
| 49 |
-
|
| 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": [
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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="#
|
| 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={
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 135 |
),
|
| 136 |
-
style={"textAlign": "right"}
|
| 137 |
)
|
| 138 |
|
|
|
|
| 139 |
# Render multiple chips in one row
|
| 140 |
-
def render_chips(metadata_list, chip_color
|
| 141 |
chips = []
|
| 142 |
for icon, name in metadata_list:
|
| 143 |
-
if isinstance(icon, str) and icon.endswith((
|
| 144 |
chips.append(
|
| 145 |
-
html.Span(
|
| 146 |
-
|
| 147 |
-
|
| 148 |
-
|
| 149 |
-
|
| 150 |
-
|
| 151 |
-
|
| 152 |
-
|
| 153 |
-
|
| 154 |
-
|
| 155 |
-
|
| 156 |
-
|
| 157 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 158 |
)
|
| 159 |
else:
|
| 160 |
chips.append(chip(f"{icon} {name}", chip_color))
|
| 161 |
return html.Div(
|
| 162 |
-
chips,
|
| 163 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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(
|
| 188 |
-
|
| 189 |
-
|
| 190 |
-
|
| 191 |
-
|
| 192 |
-
|
| 193 |
-
|
| 194 |
-
|
| 195 |
-
|
| 196 |
-
|
| 197 |
-
|
| 198 |
-
|
| 199 |
-
|
| 200 |
-
|
| 201 |
-
|
| 202 |
-
|
| 203 |
-
|
| 204 |
-
|
| 205 |
-
|
| 206 |
-
|
| 207 |
-
|
| 208 |
-
|
| 209 |
-
|
| 210 |
-
|
| 211 |
-
|
| 212 |
-
html.
|
| 213 |
-
"
|
| 214 |
-
|
| 215 |
-
|
| 216 |
-
|
| 217 |
-
|
| 218 |
-
|
| 219 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 220 |
|
| 221 |
# Function to get top N leaderboard
|
| 222 |
def get_top_n_leaderboard(filtered_df, group_col, top_n=10):
|
| 223 |
-
top =
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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(
|
|
|
|
|
|
|
| 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(
|
|
|
|
|
|
|
| 327 |
# Merge International and Online
|
| 328 |
-
filtered_df["org_country_single"] = filtered_df["org_country_single"].replace(
|
|
|
|
|
|
|
| 329 |
|
| 330 |
# Build leaderboards
|
| 331 |
-
top_countries, download_top_countries = get_top_n_leaderboard(
|
| 332 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 337 |
elif board_type == "developers":
|
| 338 |
-
return render_table(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 339 |
else:
|
| 340 |
-
return render_table(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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 |
+
)
|