sdvplot 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- sdvplot/__init__.py +68 -0
- sdvplot/_cache.py +484 -0
- sdvplot/_colors.py +206 -0
- sdvplot/_contrast.py +60 -0
- sdvplot/_court.py +110 -0
- sdvplot/_deprecate.py +39 -0
- sdvplot/_dispatch.py +342 -0
- sdvplot/_errors.py +93 -0
- sdvplot/_headshots.py +131 -0
- sdvplot/_images.py +292 -0
- sdvplot/_index.py +178 -0
- sdvplot/_lazy.py +15 -0
- sdvplot/_manifest.py +73 -0
- sdvplot/_marks.py +296 -0
- sdvplot/_normalize.py +82 -0
- sdvplot/_placement.py +168 -0
- sdvplot/_resolve.py +363 -0
- sdvplot/_surface.py +220 -0
- sdvplot/_tables.py +87 -0
- sdvplot/_tiers.py +135 -0
- sdvplot/_types.py +38 -0
- sdvplot/_versions.py +30 -0
- sdvplot/_web.py +61 -0
- sdvplot/altair.py +652 -0
- sdvplot/bokeh.py +323 -0
- sdvplot/data/INDEX_VERSION +1 -0
- sdvplot/data/aliases.parquet +0 -0
- sdvplot/data/teams.parquet +0 -0
- sdvplot/folium.py +316 -0
- sdvplot/great_tables/__init__.py +267 -0
- sdvplot/great_tables/_cells.py +1814 -0
- sdvplot/great_tables/_export.py +844 -0
- sdvplot/great_tables/_layout.py +1802 -0
- sdvplot/great_tables/_marks.py +798 -0
- sdvplot/great_tables/_themes.py +2134 -0
- sdvplot/holoviews.py +303 -0
- sdvplot/matplotlib.py +934 -0
- sdvplot/plotly.py +595 -0
- sdvplot/plotnine.py +1104 -0
- sdvplot/plottable.py +141 -0
- sdvplot/py.typed +0 -0
- sdvplot/pygal.py +416 -0
- sdvplot/reactable.py +488 -0
- sdvplot/testing.py +579 -0
- sdvplot/typing.py +21 -0
- sdvplot-0.1.0.dist-info/METADATA +188 -0
- sdvplot-0.1.0.dist-info/RECORD +49 -0
- sdvplot-0.1.0.dist-info/WHEEL +4 -0
- sdvplot-0.1.0.dist-info/licenses/LICENSE +21 -0
sdvplot/reactable.py
ADDED
|
@@ -0,0 +1,488 @@
|
|
|
1
|
+
"""reactable-py columns (``pip install sdvplot[reactable]``), ported from sdvplotR's ``reactable_sdv_*`` functions.
|
|
2
|
+
|
|
3
|
+
Each function returns ``reactable.Column`` objects for ``Reactable(columns=[...])``; pass the column's ``id`` (and any
|
|
4
|
+
other ``Column`` argument) as keywords. reactable-py runs the cell functions when the ``Reactable`` is built, so an
|
|
5
|
+
unknown value warns then, once per distinct value per column.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
import html
|
|
11
|
+
import math
|
|
12
|
+
import numbers
|
|
13
|
+
from typing import Any
|
|
14
|
+
|
|
15
|
+
from sdvplot._errors import InputError, requires_extra
|
|
16
|
+
|
|
17
|
+
with requires_extra("reactable"):
|
|
18
|
+
import narwhals as nw
|
|
19
|
+
from reactable import Column
|
|
20
|
+
from reactable.models import CellInfo
|
|
21
|
+
|
|
22
|
+
from sdvplot._colors import team_colors
|
|
23
|
+
from sdvplot._contrast import hex6
|
|
24
|
+
from sdvplot._normalize import norm_season
|
|
25
|
+
from sdvplot._placement import KINDS, _missing, check_alpha
|
|
26
|
+
from sdvplot._tables import check_px, img_tag, mark_html
|
|
27
|
+
from sdvplot._types import IdSystem, Which
|
|
28
|
+
|
|
29
|
+
__all__ = [
|
|
30
|
+
"reactable_sdv_cols_label",
|
|
31
|
+
"reactable_sdv_headshots",
|
|
32
|
+
"reactable_sdv_logos",
|
|
33
|
+
"reactable_sdv_team_color_bar",
|
|
34
|
+
"reactable_sdv_team_color_bg",
|
|
35
|
+
"reactable_sdv_wordmarks",
|
|
36
|
+
]
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def __dir__() -> list[str]: # dir() and tab completion show the public API only
|
|
40
|
+
return list(__all__)
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def _image_column(
|
|
44
|
+
kind: str,
|
|
45
|
+
league: str,
|
|
46
|
+
height: Any,
|
|
47
|
+
*,
|
|
48
|
+
season: Any = None,
|
|
49
|
+
variant: str = "default",
|
|
50
|
+
include_name: bool = False,
|
|
51
|
+
default_img: str | None = None,
|
|
52
|
+
id_system: str = "auto",
|
|
53
|
+
strict: bool = False,
|
|
54
|
+
column_kwargs: dict[str, Any],
|
|
55
|
+
) -> Column:
|
|
56
|
+
h = check_px(height)
|
|
57
|
+
norm_season(season, league=league) # one season for the column: fail now, not inside reactable
|
|
58
|
+
rendered: dict[str, str] = {}
|
|
59
|
+
|
|
60
|
+
def cell(info: CellInfo) -> str:
|
|
61
|
+
value = info.value
|
|
62
|
+
if _missing(value):
|
|
63
|
+
return ""
|
|
64
|
+
key = str(value)
|
|
65
|
+
if key not in rendered: # resolve each distinct value once: one warning per unknown value
|
|
66
|
+
(img,) = mark_html([value], league=league, kind=kind, height=h, season=season, variant=variant,
|
|
67
|
+
id_system=id_system, strict=strict, include_name=include_name) # fmt: skip
|
|
68
|
+
text = html.escape(key)
|
|
69
|
+
if img is None and default_img is not None:
|
|
70
|
+
img = img_tag(default_img, h, key, margin=include_name)
|
|
71
|
+
rendered[key] = text if img is None else img + (text if include_name else "")
|
|
72
|
+
return rendered[key]
|
|
73
|
+
|
|
74
|
+
return Column(**{"html": True, **column_kwargs, "cell": cell})
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def reactable_sdv_logos(
|
|
78
|
+
*,
|
|
79
|
+
league: str,
|
|
80
|
+
variant: str = "default",
|
|
81
|
+
height: Any = 30,
|
|
82
|
+
default_img: str | None = None,
|
|
83
|
+
season: Any = None,
|
|
84
|
+
include_name: bool = False,
|
|
85
|
+
id_system: IdSystem = "auto",
|
|
86
|
+
strict: bool = False,
|
|
87
|
+
**column_kwargs: Any,
|
|
88
|
+
) -> Column:
|
|
89
|
+
"""A reactable column that shows each cell's team as its logo.
|
|
90
|
+
|
|
91
|
+
Args:
|
|
92
|
+
league: The SDV league key, e.g. "nfl".
|
|
93
|
+
variant: "default", "dark", or a named variant from ``marks()``.
|
|
94
|
+
height: The image height in pixels.
|
|
95
|
+
default_img: An image URL for values that do not resolve; None keeps their text.
|
|
96
|
+
season: One season whose marks every cell shows; None for today's.
|
|
97
|
+
include_name: Keep the cell's text after the logo.
|
|
98
|
+
id_system: The id system of the column's values, as in ``resolve``: "auto" tries each in order; NHL stats
|
|
99
|
+
ids need "nhl_id".
|
|
100
|
+
strict: Raise UnresolvedTeamError (when the ``Reactable`` is built) instead of warning when a value does not
|
|
101
|
+
resolve.
|
|
102
|
+
**column_kwargs: Passed to ``reactable.Column``: ``id`` (the data column, required by reactable), ``name``,
|
|
103
|
+
``width``, ...
|
|
104
|
+
|
|
105
|
+
Returns:
|
|
106
|
+
reactable.Column: The column, with ``html=True`` and a cell renderer.
|
|
107
|
+
|
|
108
|
+
Raises:
|
|
109
|
+
InputError: (a ValueError) If ``height`` is not a number of pixels of at least 1, or ``season`` is not one year
|
|
110
|
+
or is outside the seasons sdvplot knows for the league; when the ``Reactable`` is built, if ``league``,
|
|
111
|
+
``id_system`` or ``variant`` is unknown.
|
|
112
|
+
UnresolvedTeamError: (a ValueError) If ``strict=True`` and a value does not resolve, when the ``Reactable`` is
|
|
113
|
+
built.
|
|
114
|
+
OfflineError: When the ``Reactable`` is built, if the logo manifest cannot be downloaded and no cached copy
|
|
115
|
+
exists (a DownloadError, also an OSError, when the CDN answers with an error status).
|
|
116
|
+
UnsafeDownloadError: (an OSError) When the ``Reactable`` is built, if the manifest download is refused: larger
|
|
117
|
+
than the byte cap, past the deadline, or redirected away from https.
|
|
118
|
+
|
|
119
|
+
Example:
|
|
120
|
+
::
|
|
121
|
+
|
|
122
|
+
from reactable import Reactable
|
|
123
|
+
from sdvplot.reactable import reactable_sdv_logos
|
|
124
|
+
import pandas as pd
|
|
125
|
+
|
|
126
|
+
df = pd.DataFrame(
|
|
127
|
+
{
|
|
128
|
+
"team": ["KC", "BUF", "BAL"],
|
|
129
|
+
"espn_id": ["3139477", "3918298", "3916387"],
|
|
130
|
+
"wins": [12, 10, 9],
|
|
131
|
+
}
|
|
132
|
+
)
|
|
133
|
+
|
|
134
|
+
Reactable(df, columns=[reactable_sdv_logos(league="nfl", id="team", name="")])
|
|
135
|
+
|
|
136
|
+
See Also:
|
|
137
|
+
Ported from sdvplotR ``reactable_sdv_logos()``:
|
|
138
|
+
https://sdvplotR.sportsdataverse.org/reference/reactable_sdv_images.html
|
|
139
|
+
"""
|
|
140
|
+
return _image_column("logo", league, height, season=season, variant=variant, include_name=include_name,
|
|
141
|
+
default_img=default_img, id_system=id_system, strict=strict,
|
|
142
|
+
column_kwargs=column_kwargs) # fmt: skip
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
def reactable_sdv_wordmarks(
|
|
146
|
+
*,
|
|
147
|
+
league: str,
|
|
148
|
+
variant: str = "default",
|
|
149
|
+
height: Any = 30,
|
|
150
|
+
default_img: str | None = None,
|
|
151
|
+
season: Any = None,
|
|
152
|
+
include_name: bool = False,
|
|
153
|
+
id_system: IdSystem = "auto",
|
|
154
|
+
strict: bool = False,
|
|
155
|
+
**column_kwargs: Any,
|
|
156
|
+
) -> Column:
|
|
157
|
+
"""A reactable column that shows each cell's team as its wordmark.
|
|
158
|
+
|
|
159
|
+
Args:
|
|
160
|
+
league: The SDV league key, e.g. "nfl".
|
|
161
|
+
variant: "default", "dark", or a named variant from ``marks()``.
|
|
162
|
+
height: The image height in pixels.
|
|
163
|
+
default_img: An image URL for values that do not resolve; None keeps their text.
|
|
164
|
+
season: One season whose marks every cell shows; None for today's.
|
|
165
|
+
include_name: Keep the cell's text after the wordmark.
|
|
166
|
+
id_system: The id system of the column's values, as in ``resolve``: "auto" tries each in order; NHL stats
|
|
167
|
+
ids need "nhl_id".
|
|
168
|
+
strict: Raise UnresolvedTeamError (when the ``Reactable`` is built) instead of warning when a value does not
|
|
169
|
+
resolve.
|
|
170
|
+
**column_kwargs: Passed to ``reactable.Column`` (``id`` is required by reactable).
|
|
171
|
+
|
|
172
|
+
Returns:
|
|
173
|
+
reactable.Column: The column, with ``html=True`` and a cell renderer.
|
|
174
|
+
|
|
175
|
+
Raises:
|
|
176
|
+
InputError: (a ValueError) If ``height`` is not a number of pixels of at least 1, or ``season`` is not one year
|
|
177
|
+
or is outside the seasons sdvplot knows for the league; when the ``Reactable`` is built, if ``league``,
|
|
178
|
+
``id_system`` or ``variant`` is unknown.
|
|
179
|
+
UnresolvedTeamError: (a ValueError) If ``strict=True`` and a value does not resolve, when the ``Reactable`` is
|
|
180
|
+
built.
|
|
181
|
+
OfflineError: When the ``Reactable`` is built, if the logo manifest cannot be downloaded and no cached copy
|
|
182
|
+
exists (a DownloadError, also an OSError, when the CDN answers with an error status).
|
|
183
|
+
UnsafeDownloadError: (an OSError) When the ``Reactable`` is built, if the manifest download is refused: larger
|
|
184
|
+
than the byte cap, past the deadline, or redirected away from https.
|
|
185
|
+
|
|
186
|
+
Example:
|
|
187
|
+
::
|
|
188
|
+
|
|
189
|
+
import pandas as pd
|
|
190
|
+
from reactable import Reactable
|
|
191
|
+
from sdvplot.reactable import reactable_sdv_wordmarks
|
|
192
|
+
|
|
193
|
+
df = pd.DataFrame(
|
|
194
|
+
{
|
|
195
|
+
"team": ["KC", "BUF", "BAL"],
|
|
196
|
+
"espn_id": ["3139477", "3918298", "3916387"],
|
|
197
|
+
"wins": [12, 10, 9],
|
|
198
|
+
}
|
|
199
|
+
)
|
|
200
|
+
|
|
201
|
+
Reactable(df, columns=[reactable_sdv_wordmarks(league="nfl", id="team")])
|
|
202
|
+
|
|
203
|
+
See Also:
|
|
204
|
+
Ported from sdvplotR ``reactable_sdv_wordmarks()``:
|
|
205
|
+
https://sdvplotR.sportsdataverse.org/reference/reactable_sdv_images.html
|
|
206
|
+
"""
|
|
207
|
+
return _image_column("wordmark", league, height, season=season, variant=variant, include_name=include_name,
|
|
208
|
+
default_img=default_img, id_system=id_system, strict=strict,
|
|
209
|
+
column_kwargs=column_kwargs) # fmt: skip
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
def reactable_sdv_headshots(
|
|
213
|
+
*,
|
|
214
|
+
league: str,
|
|
215
|
+
height: Any = 40,
|
|
216
|
+
default_img: str | None = None,
|
|
217
|
+
id_system: str = "espn",
|
|
218
|
+
**column_kwargs: Any,
|
|
219
|
+
) -> Column:
|
|
220
|
+
"""A reactable column that shows each cell's player id as the player's headshot.
|
|
221
|
+
|
|
222
|
+
Args:
|
|
223
|
+
league: The SDV league key, e.g. "nfl".
|
|
224
|
+
height: The image height in pixels.
|
|
225
|
+
default_img: An image URL for ids without a headshot; None keeps their text.
|
|
226
|
+
id_system: "espn" (ESPN athlete ids) or "gsis" (NFL), as in ``headshot_url``.
|
|
227
|
+
**column_kwargs: Passed to ``reactable.Column`` (``id`` is required by reactable).
|
|
228
|
+
|
|
229
|
+
Returns:
|
|
230
|
+
reactable.Column: The column, with ``html=True`` and a cell renderer.
|
|
231
|
+
|
|
232
|
+
Raises:
|
|
233
|
+
InputError: (a ValueError) If ``height`` is not a number of pixels of at least 1; when the ``Reactable`` is
|
|
234
|
+
built, if ``league`` has no ESPN headshots or ``id_system`` is not valid for ``league``.
|
|
235
|
+
OfflineError: When the ``Reactable`` is built, if ``id_system`` is "gsis" and the nflverse player table cannot
|
|
236
|
+
be downloaded and no cached copy exists (a DownloadError, also an OSError, for an HTTP error status).
|
|
237
|
+
UnsafeDownloadError: (an OSError) When the ``Reactable`` is built, if ``id_system`` is "gsis" and the player
|
|
238
|
+
table download is refused: larger than the byte cap, past the deadline, or redirected away from https.
|
|
239
|
+
|
|
240
|
+
Example:
|
|
241
|
+
::
|
|
242
|
+
|
|
243
|
+
import pandas as pd
|
|
244
|
+
from reactable import Reactable
|
|
245
|
+
from sdvplot.reactable import reactable_sdv_headshots
|
|
246
|
+
|
|
247
|
+
df = pd.DataFrame(
|
|
248
|
+
{
|
|
249
|
+
"team": ["KC", "BUF", "BAL"],
|
|
250
|
+
"espn_id": ["3139477", "3918298", "3916387"],
|
|
251
|
+
"wins": [12, 10, 9],
|
|
252
|
+
}
|
|
253
|
+
)
|
|
254
|
+
|
|
255
|
+
Reactable(df, columns=[reactable_sdv_headshots(league="nfl", id="espn_id", name="")])
|
|
256
|
+
|
|
257
|
+
See Also:
|
|
258
|
+
Ported from sdvplotR ``reactable_sdv_headshots()``:
|
|
259
|
+
https://sdvplotR.sportsdataverse.org/reference/reactable_sdv_images.html
|
|
260
|
+
"""
|
|
261
|
+
return _image_column("headshot", league, height, default_img=default_img, id_system=id_system,
|
|
262
|
+
column_kwargs=column_kwargs) # fmt: skip
|
|
263
|
+
|
|
264
|
+
|
|
265
|
+
def reactable_sdv_cols_label(
|
|
266
|
+
data: Any,
|
|
267
|
+
*,
|
|
268
|
+
league: str,
|
|
269
|
+
variant: str = "default",
|
|
270
|
+
height: Any = 30,
|
|
271
|
+
season: Any = None,
|
|
272
|
+
mark_type: str = "logo",
|
|
273
|
+
id_system: IdSystem = "auto",
|
|
274
|
+
strict: bool = False,
|
|
275
|
+
**column_kwargs: Any,
|
|
276
|
+
) -> list[Column]:
|
|
277
|
+
"""One reactable column per team-named column of ``data`` (a ``KC`` column, a ``BUF`` column, ...), its header
|
|
278
|
+
the team's mark.
|
|
279
|
+
|
|
280
|
+
Args:
|
|
281
|
+
data: The pandas or polars DataFrame passed to ``Reactable``. Pass only the team-named columns
|
|
282
|
+
(``df[["KC", "BUF"]]``) to avoid a warning for the others.
|
|
283
|
+
league: The SDV league key, e.g. "nfl".
|
|
284
|
+
variant: "default", "dark", or a named variant from ``marks()``.
|
|
285
|
+
height: The image height in pixels.
|
|
286
|
+
season: One season whose marks to show; None for today's.
|
|
287
|
+
mark_type: "logo" or "wordmark".
|
|
288
|
+
id_system: The id system of the column names, as in ``resolve``: "auto" tries each in order; NHL stats ids
|
|
289
|
+
need "nhl_id".
|
|
290
|
+
strict: Raise UnresolvedTeamError instead of warning when a column name does not resolve.
|
|
291
|
+
**column_kwargs: Passed to every ``reactable.Column``.
|
|
292
|
+
|
|
293
|
+
Returns:
|
|
294
|
+
list[reactable.Column]: A column (``id`` = the column name, an empty ``name``, the mark as ``header``) for each
|
|
295
|
+
column whose name resolves; the others are left out, with one SdvplotWarning.
|
|
296
|
+
|
|
297
|
+
Raises:
|
|
298
|
+
InputError: (a ValueError) If ``mark_type`` is not "logo"/"wordmark", ``height`` is not a number of pixels of at
|
|
299
|
+
least 1, ``league``, ``id_system`` or ``variant`` is unknown, or ``season`` is not one year or is outside
|
|
300
|
+
the seasons sdvplot knows for the league.
|
|
301
|
+
UnresolvedTeamError: (a ValueError) If ``strict=True`` and a column name does not resolve.
|
|
302
|
+
OfflineError: If the logo manifest cannot be downloaded and no cached copy exists (a DownloadError, also an
|
|
303
|
+
OSError, when the CDN answers with an error status).
|
|
304
|
+
UnsafeDownloadError: (an OSError) If the manifest download is refused: larger than the byte cap, past the
|
|
305
|
+
deadline, or redirected away from https.
|
|
306
|
+
|
|
307
|
+
Example:
|
|
308
|
+
::
|
|
309
|
+
|
|
310
|
+
import pandas as pd
|
|
311
|
+
from reactable import Reactable
|
|
312
|
+
from sdvplot.reactable import reactable_sdv_cols_label
|
|
313
|
+
|
|
314
|
+
df = pd.DataFrame(
|
|
315
|
+
{
|
|
316
|
+
"team": ["KC", "BUF", "BAL"],
|
|
317
|
+
"espn_id": ["3139477", "3918298", "3916387"],
|
|
318
|
+
"wins": [12, 10, 9],
|
|
319
|
+
}
|
|
320
|
+
)
|
|
321
|
+
|
|
322
|
+
Reactable(df, columns=reactable_sdv_cols_label(df, league="nfl"))
|
|
323
|
+
|
|
324
|
+
See Also:
|
|
325
|
+
Ported from sdvplotR ``reactable_sdv_cols_label()``:
|
|
326
|
+
https://sdvplotR.sportsdataverse.org/reference/reactable_sdv_cols_label.html
|
|
327
|
+
"""
|
|
328
|
+
h = check_px(height)
|
|
329
|
+
if mark_type not in KINDS[:2]:
|
|
330
|
+
raise InputError(f"mark_type must be 'logo' or 'wordmark', got {mark_type!r}")
|
|
331
|
+
names = list(nw.from_native(data, eager_only=True).columns)
|
|
332
|
+
imgs = mark_html(names, league=league, kind=mark_type, height=h, season=season, variant=variant,
|
|
333
|
+
id_system=id_system, strict=strict) # fmt: skip
|
|
334
|
+
return [
|
|
335
|
+
Column(**{"name": "", "html": True, **column_kwargs, "id": name, "header": img})
|
|
336
|
+
for name, img in zip(names, imgs, strict=True)
|
|
337
|
+
if img is not None
|
|
338
|
+
]
|
|
339
|
+
|
|
340
|
+
|
|
341
|
+
def _row_colors(
|
|
342
|
+
data: Any, team_col: str, league: str, which: Which, na_color: str, id_system: IdSystem, strict: bool
|
|
343
|
+
) -> tuple[Any, list[str]]:
|
|
344
|
+
frame = nw.from_native(data, eager_only=True)
|
|
345
|
+
if team_col not in frame.columns:
|
|
346
|
+
raise ValueError(f"column {team_col!r} not found in data; columns are {frame.columns}")
|
|
347
|
+
colors = team_colors(league, frame[team_col].to_list(), which=which, id_system=id_system, strict=strict)
|
|
348
|
+
return frame, [c or na_color for c in colors]
|
|
349
|
+
|
|
350
|
+
|
|
351
|
+
def reactable_sdv_team_color_bar(
|
|
352
|
+
data: Any,
|
|
353
|
+
team_col: str,
|
|
354
|
+
*,
|
|
355
|
+
league: str,
|
|
356
|
+
which: Which = "primary",
|
|
357
|
+
max_value: float | None = None,
|
|
358
|
+
na_color: str = "#b3b3b3",
|
|
359
|
+
id_system: IdSystem = "auto",
|
|
360
|
+
strict: bool = False,
|
|
361
|
+
**column_kwargs: Any,
|
|
362
|
+
) -> Column:
|
|
363
|
+
"""A reactable column whose cells hold a bar in the row's team color, as long as the value's share of the maximum.
|
|
364
|
+
|
|
365
|
+
Args:
|
|
366
|
+
data: The pandas or polars DataFrame passed to ``Reactable`` (each row's team is read from it).
|
|
367
|
+
team_col: The column of ``data`` holding the teams.
|
|
368
|
+
league: The SDV league key, e.g. "nfl".
|
|
369
|
+
which: "primary" or "secondary" team color.
|
|
370
|
+
max_value: The value that fills the whole cell; None for the column's maximum.
|
|
371
|
+
na_color: The CSS color for teams that do not resolve or have no color.
|
|
372
|
+
id_system: The id system of ``team_col``, as in ``resolve``: "auto" tries each in order; NHL stats ids need
|
|
373
|
+
"nhl_id".
|
|
374
|
+
strict: Raise UnresolvedTeamError instead of warning when a team does not resolve.
|
|
375
|
+
**column_kwargs: Passed to ``reactable.Column``; ``id`` names the styled column.
|
|
376
|
+
|
|
377
|
+
Returns:
|
|
378
|
+
reactable.Column: The column, with a ``style`` function.
|
|
379
|
+
|
|
380
|
+
Raises:
|
|
381
|
+
InputError: (a ValueError) If ``league`` or ``id_system`` is unknown, or ``which`` is not "primary"/"secondary".
|
|
382
|
+
ValueError: If ``team_col`` is not a column of ``data``.
|
|
383
|
+
UnresolvedTeamError: (a ValueError) If ``strict=True`` and a team does not resolve.
|
|
384
|
+
|
|
385
|
+
Example:
|
|
386
|
+
::
|
|
387
|
+
|
|
388
|
+
import pandas as pd
|
|
389
|
+
from reactable import Reactable
|
|
390
|
+
from sdvplot.reactable import reactable_sdv_team_color_bar
|
|
391
|
+
|
|
392
|
+
df = pd.DataFrame(
|
|
393
|
+
{
|
|
394
|
+
"team": ["KC", "BUF", "BAL"],
|
|
395
|
+
"espn_id": ["3139477", "3918298", "3916387"],
|
|
396
|
+
"wins": [12, 10, 9],
|
|
397
|
+
}
|
|
398
|
+
)
|
|
399
|
+
|
|
400
|
+
Reactable(df, columns=[reactable_sdv_team_color_bar(df, "team", league="nfl", id="wins")])
|
|
401
|
+
|
|
402
|
+
See Also:
|
|
403
|
+
Ported from sdvplotR ``reactable_sdv_team_color_bar()``:
|
|
404
|
+
https://sdvplotR.sportsdataverse.org/reference/reactable_sdv_team_color.html
|
|
405
|
+
"""
|
|
406
|
+
frame, colors = _row_colors(data, team_col, league, which, na_color, id_system, strict)
|
|
407
|
+
tops: dict[str, float] = {}
|
|
408
|
+
|
|
409
|
+
def top(column: str) -> float:
|
|
410
|
+
if column not in tops:
|
|
411
|
+
values = [float(v) for v in frame[column].to_list() if isinstance(v, numbers.Real) and not _missing(v)]
|
|
412
|
+
tops[column] = max_value if max_value is not None else max(values, default=math.nan)
|
|
413
|
+
return tops[column]
|
|
414
|
+
|
|
415
|
+
def bar(info: CellInfo) -> dict[str, str]:
|
|
416
|
+
value, t = info.value, top(info.column_name)
|
|
417
|
+
ok = isinstance(value, numbers.Real) and not _missing(value) and math.isfinite(t) and t != 0
|
|
418
|
+
pct = round(100 * value / t, 1) if ok else 0
|
|
419
|
+
c = colors[info.row_index]
|
|
420
|
+
return {"background-image": f"linear-gradient(90deg, {c} {pct:g}%, transparent {pct:g}%)"}
|
|
421
|
+
|
|
422
|
+
return Column(**{**column_kwargs, "style": bar})
|
|
423
|
+
|
|
424
|
+
|
|
425
|
+
def reactable_sdv_team_color_bg(
|
|
426
|
+
data: Any,
|
|
427
|
+
team_col: str,
|
|
428
|
+
*,
|
|
429
|
+
league: str,
|
|
430
|
+
which: Which = "primary",
|
|
431
|
+
alpha: float = 0.15,
|
|
432
|
+
na_color: str = "#b3b3b3",
|
|
433
|
+
id_system: IdSystem = "auto",
|
|
434
|
+
strict: bool = False,
|
|
435
|
+
**column_kwargs: Any,
|
|
436
|
+
) -> Column:
|
|
437
|
+
"""A reactable column whose cells are filled with the row's team color, mostly transparent.
|
|
438
|
+
|
|
439
|
+
Args:
|
|
440
|
+
data: The pandas or polars DataFrame passed to ``Reactable`` (each row's team is read from it).
|
|
441
|
+
team_col: The column of ``data`` holding the teams.
|
|
442
|
+
league: The SDV league key, e.g. "nfl".
|
|
443
|
+
which: "primary" or "secondary" team color.
|
|
444
|
+
alpha: The fill's opacity, 0 to 1.
|
|
445
|
+
na_color: The hex color for teams that do not resolve or have no color.
|
|
446
|
+
id_system: The id system of ``team_col``, as in ``resolve``: "auto" tries each in order; NHL stats ids need
|
|
447
|
+
"nhl_id".
|
|
448
|
+
strict: Raise UnresolvedTeamError instead of warning when a team does not resolve.
|
|
449
|
+
**column_kwargs: Passed to ``reactable.Column``; ``id`` names the styled column.
|
|
450
|
+
|
|
451
|
+
Returns:
|
|
452
|
+
reactable.Column: The column, with a ``style`` function.
|
|
453
|
+
|
|
454
|
+
Raises:
|
|
455
|
+
InputError: (a ValueError) If ``alpha`` is outside [0, 1], ``league`` or ``id_system`` is unknown, or ``which``
|
|
456
|
+
is not "primary"/"secondary".
|
|
457
|
+
ValueError: If ``team_col`` is not a column of ``data``, or ``na_color`` is not a hex color.
|
|
458
|
+
UnresolvedTeamError: (a ValueError) If ``strict=True`` and a team does not resolve.
|
|
459
|
+
|
|
460
|
+
Example:
|
|
461
|
+
::
|
|
462
|
+
|
|
463
|
+
import pandas as pd
|
|
464
|
+
from reactable import Reactable
|
|
465
|
+
from sdvplot.reactable import reactable_sdv_team_color_bg
|
|
466
|
+
|
|
467
|
+
df = pd.DataFrame(
|
|
468
|
+
{
|
|
469
|
+
"team": ["KC", "BUF", "BAL"],
|
|
470
|
+
"espn_id": ["3139477", "3918298", "3916387"],
|
|
471
|
+
"wins": [12, 10, 9],
|
|
472
|
+
}
|
|
473
|
+
)
|
|
474
|
+
|
|
475
|
+
Reactable(df, columns=[reactable_sdv_team_color_bg(df, "team", league="nfl", id="team")])
|
|
476
|
+
|
|
477
|
+
See Also:
|
|
478
|
+
Ported from sdvplotR ``reactable_sdv_team_color_bg()``:
|
|
479
|
+
https://sdvplotR.sportsdataverse.org/reference/reactable_sdv_team_color.html
|
|
480
|
+
"""
|
|
481
|
+
a = check_alpha(alpha)
|
|
482
|
+
_, colors = _row_colors(data, team_col, league, which, na_color, id_system, strict)
|
|
483
|
+
fills = [f"{hex6(c, drop_alpha=True)}{round(a * 255):02x}" for c in colors] # alpha replaces any in na_color
|
|
484
|
+
|
|
485
|
+
def fill(info: CellInfo) -> dict[str, str]:
|
|
486
|
+
return {"background-color": fills[info.row_index]}
|
|
487
|
+
|
|
488
|
+
return Column(**{**column_kwargs, "style": fill})
|