Index Plot
Index plots comparing group performance against a baseline, where a raw index of 100 is parity.
Use index.plot for relative performance against a reference category; plots.time for raw
values over time; plots.bar for categorical comparison. plot() draws the bars;
get_indexes() computes the index values.
filter_by_groups(df, group_col, exclude_groups=None, include_only_groups=None)
Filter dataframe by groups.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
df
|
DataFrame
|
The dataframe to filter. |
required |
group_col
|
str
|
The column name for grouping. |
required |
exclude_groups
|
list[Any]
|
Groups to exclude. Defaults to None. |
None
|
include_only_groups
|
list[Any]
|
Groups to include. Defaults to None. |
None
|
Returns:
| Type | Description |
|---|---|
DataFrame
|
pd.DataFrame: The filtered dataframe. |
Source code in openretailscience/plots/index.py
filter_by_value_thresholds(df, filter_above=None, filter_below=None)
Filter a dataframe by index value thresholds.
Expects the index column in delta-from-baseline form (raw index minus 100), as plot uses;
thresholds are in raw-index units (filter_above=120 keeps rows whose raw index exceeds 120).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
df
|
DataFrame
|
The dataframe to filter. |
required |
filter_above
|
float
|
Only keep rows whose raw index exceeds this value. |
None
|
filter_below
|
float
|
Only keep rows whose raw index is below this value. |
None
|
Returns:
| Type | Description |
|---|---|
DataFrame
|
pd.DataFrame: The filtered dataframe. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
ValueError
|
If filtering results in an empty dataset. |
Source code in openretailscience/plots/index.py
filter_top_bottom_n(df, top_n=None, bottom_n=None)
Filter a dataframe to the top N and/or bottom N rows by index value.
Rows are ranked by the index column, descending. 0 is treated as None for both
parameters; an empty df is returned unchanged.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
df
|
DataFrame
|
The dataframe to filter. |
required |
top_n
|
int
|
Number of top rows to include. |
None
|
bottom_n
|
int
|
Number of bottom rows to include. |
None
|
Returns:
| Type | Description |
|---|---|
DataFrame
|
pd.DataFrame: The filtered dataframe. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If top_n or bottom_n exceeds the number of available groups. |
ValueError
|
If the sum of top_n and bottom_n exceeds the number of groups. |
Source code in openretailscience/plots/index.py
get_indexes(df, value_to_index, index_col, value_col, group_col, index_subgroup_col=None, agg_func='sum', offset=0)
Calculate each group's index of value_col against a baseline category.
Index = 100 * (group share of the aggregated value_col among rows where index_col ==
value_to_index) / (group share of the aggregated value_col overall) - offset. When
index_subgroup_col is set, shares are computed within each subgroup instead of
overall.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
df
|
DataFrame | Table
|
The dataframe or Ibis table to calculate the index on. |
required |
value_to_index
|
str
|
The baseline category or value to index against (e.g., "A"). |
required |
index_col
|
str
|
The column to calculate the index on (e.g., "category"). |
required |
value_col
|
str
|
The column to calculate the index of (e.g., "sales"). |
required |
group_col
|
str
|
The column to group the data by (e.g., "region"). |
required |
index_subgroup_col
|
str
|
The column to subgroup the index by (e.g., "store_type"). |
None
|
agg_func
|
str
|
The aggregation function to apply to |
'sum'
|
offset
|
int
|
Subtracted from the computed index. Defaults to 0; |
0
|
Returns:
| Type | Description |
|---|---|
DataFrame
|
pd.DataFrame: The group columns plus an |
Raises:
| Type | Description |
|---|---|
ValueError
|
If agg_func is not one of "sum", "mean", "max", "min", or "nunique". |
Source code in openretailscience/plots/index.py
394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 | |
plot(df, value_col, group_col, index_col, value_to_index, agg_func='sum', series_col=None, title=None, eyebrow=None, subtitle=None, x_label=None, y_label=None, legend_title=None, move_legend_outside=False, highlight_range='default', sort_by='group', sort_order='ascending', ax=None, source_text=None, exclude_groups=None, include_only_groups=None, drop_na=False, top_n=None, bottom_n=None, filter_above=None, filter_below=None, color_by_threshold=False, **kwargs)
Create a horizontal bar index plot comparing each group's performance against a baseline.
The index for each group is
100 * (group share of the aggregated value_col among rows where index_col ==
value_to_index) / (group share of the aggregated value_col overall) - 100,
so a delta of 0 is parity; bars are drawn from the 100 baseline outward, with a vertical
baseline line at 100.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
df
|
DataFrame
|
The dataframe to plot. |
required |
value_col
|
str
|
The column to plot. |
required |
group_col
|
str
|
The column to group the data by. |
required |
index_col
|
str
|
The column to calculate the index on (e.g., "category"). |
required |
value_to_index
|
str
|
The baseline category or value to index against (e.g., "A"). |
required |
agg_func
|
str
|
How to aggregate |
'sum'
|
series_col
|
str
|
The column to use as the series; when set, a legend is rendered
and each series value gets its own bar per group. |
None
|
title
|
str
|
The title of the plot. |
None
|
eyebrow
|
str
|
Small uppercase label rendered above the title. |
None
|
subtitle
|
str
|
Supporting copy rendered below the title. |
None
|
x_label
|
str
|
X-axis label; omitted means no label. |
None
|
y_label
|
str
|
Y-axis label; omitted means no label. |
None
|
legend_title
|
str
|
The title of the legend. |
None
|
move_legend_outside
|
bool
|
Whether to move the legend outside the plot area. |
False
|
highlight_range
|
Literal['default'] | tuple[float, float] | None
|
The range to highlight with a shaded span and vertical lines at the bounds. "default" means (80, 120); None disables it. |
'default'
|
sort_by
|
Literal['group', 'value'] | None
|
"group" sorts by |
'group'
|
sort_order
|
Literal['asc', 'ascending', 'desc', 'descending']
|
The sort order. Accepts short or long forms, case-insensitive. |
'ascending'
|
ax
|
Axes
|
The matplotlib axes object to plot on. |
None
|
source_text
|
str
|
The source text to add to the plot. |
None
|
exclude_groups
|
list[Any]
|
The groups to exclude from the plot. |
None
|
include_only_groups
|
list[Any]
|
The groups to include in the plot. Cannot be used
with |
None
|
drop_na
|
bool
|
Whether to drop NA index values. |
False
|
top_n
|
int
|
Display only the top N indexes. Only applicable when |
None
|
bottom_n
|
int
|
Display only the bottom N indexes. Only applicable when
|
None
|
filter_above
|
float
|
Only display groups whose raw index exceeds this value.
Only applicable when |
None
|
filter_below
|
float
|
Only display groups whose raw index is below this value.
Only applicable when |
None
|
color_by_threshold
|
bool
|
Color bars by the |
False
|
**kwargs
|
Any
|
Additional keyword arguments, normally passed to pandas' |
{}
|
Returns:
| Name | Type | Description |
|---|---|---|
SubplotBase |
SubplotBase
|
The matplotlib axes object. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If sort_by is not "group", "value", or None. |
ValueError
|
If agg_func is not one of "sum", "mean", "max", "min", or "nunique". |
ValueError
|
If sort_by is "value" and series_col is provided. |
ValueError
|
If sort_order is not one of "asc", "ascending", "desc", or "descending". |
ValueError
|
If exclude_groups and include_only_groups are used together. |
ValueError
|
If top_n, bottom_n, filter_above, or filter_below are used when series_col is provided. |
ValueError
|
If color_by_threshold is True but highlight_range is None. |
ValueError
|
If color_by_threshold is True when series_col is provided. |
ValueError
|
If filter_above is not strictly less than filter_below. |
ValueError
|
If filtering results in an empty dataset. |
ValueError
|
If top_n or bottom_n exceeds the number of available groups. |
ValueError
|
If top_n and bottom_n together exceed the number of available groups. |
Source code in openretailscience/plots/index.py
149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 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 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 | |