import polars as pl
import polars.selectors as cs
from great_tables import GT, md
def create_bar(prop_fill: float, max_width: int, height: int) -> str:
"""Create divs to represent prop_fill as a bar."""
width = round(max_width * prop_fill, 2)
px_width = f"{width}px"
return f"""\
<div style="width: {max_width}px; background-color: lightgrey;">\
<div style="height:{height}px;width:{px_width};background-color:green;"></div>\
</div>\
"""
df = pl.read_csv("./sports_earnings.csv")
res = (
df.with_columns(
(pl.col("Off-the-Field Earnings") / pl.col("Total Earnings")).alias("raw_perc"),
(pl.col("Sport").str.to_lowercase() + ".png").alias("icon"),
)
.head(9)
.with_columns(
pl.col("raw_perc")
.map_elements(lambda x: create_bar(x, max_width=75, height=20))
.alias("Off-the-Field Earnings Perc")
)
.select("Rank", "Name", "icon", "Sport", "Total Earnings", "Off-the-Field Earnings", "Off-the-Field Earnings Perc")
)
(
GT(res, rowname_col="Rank")
.tab_header("Highest Paid Athletes in 2023")
.tab_spanner("Earnings", cs.contains("Earnings"))
#.fmt_number(cs.starts_with("Total"), scale_by = 1/1_000_000, decimals=1)
.cols_label(**{
"Total Earnings": "Total $M",
"Off-the-Field Earnings": "Off field $M",
"Off-the-Field Earnings Perc": "Off field %"
})
.fmt_number(["Total Earnings", "Off-the-Field Earnings"], scale_by = 1/1_000_000, decimals=1)
.fmt_image("icon", path="./")
.tab_source_note(
md(
'<br><div style="text-align: center;">'
"Original table: [@LisaHornung_](https://twitter.com/LisaHornung_/status/1752981867769266231)"
" | Sports icons: [Firza Alamsyah](https://thenounproject.com/browse/collection-icon/sports-96427)"
" | Data: Forbes"
"</div>"
"<br>"
)
)
)| Highest Paid Athletes in 2023 | ||||||
|---|---|---|---|---|---|---|
| Name | icon | Sport | Earnings | |||
| Total $M | Off field $M | Off field % | ||||
| 1 | Cristiano Ronaldo | Soccer | 136.0 | 90.0 | |
|
| 2 | Lionel Messi | Soccer | 130.0 | 65.0 | |
|
| 3 | Kylian Mbappé | Soccer | 120.0 | 20.0 | |
|
| 4 | LeBron James | Basketball | 119.5 | 75.0 | |
|
| 5 | Canelo Alvarez | Boxing | 110.0 | 10.0 | |
|
| 6 | Dustin Johnson | Golf | 107.0 | 5.0 | |
|
| 7 | Phil Mickelson | Golf | 106.0 | 2.0 | |
|
| 8 | Stephen Curry | Basketball | 100.4 | 52.0 | |
|
| 9 | Roger Federer | Tennis | 95.1 | 95.0 | |
|
Original table: @LisaHornung_ | Sports icons: Firza Alamsyah | Data: Forbes |
||||||