Skip to content

fix(metrics): GroupBy(ValueDrift) widget keeps decorated display name (#1706)#1876

Open
jbbqqf wants to merge 1 commit into
evidentlyai:mainfrom
jbbqqf:fix/1706-groupby-valuedrift-display-name
Open

fix(metrics): GroupBy(ValueDrift) widget keeps decorated display name (#1706)#1876
jbbqqf wants to merge 1 commit into
evidentlyai:mainfrom
jbbqqf:fix/1706-groupby-valuedrift-display-name

Conversation

@jbbqqf
Copy link
Copy Markdown

@jbbqqf jbbqqf commented May 9, 2026

Summary

Closes #1706.

`ValueDriftCalculation._render` hard-coded the widget title as
`f"Drift in column '{result.column_name}'"` (see
`src/evidently/metrics/column_statistics.py`). When the calculation is
wrapped in `GroupBy(...)`, `GroupByMetricCalculation.calculate` patches
`self.calculation.display_name` so that other metrics (MaxValue, MeanValue,
…) pick up the "group by '<col>' for label: '<label>'" suffix at render
time — they call `self.display_name()` from `StatisticsCalculation.calculate`.
ValueDrift never read the patched name, so its widget always rendered the
bare column name regardless of how it was wrapped, which is exactly the
bug reported in #1706.

Fix

`src/evidently/metrics/column_statistics.py`:

  • Pass the GroupBy-decorated `display_name()` through to `_render` only
    when it carries the GroupBy suffix (`" group by '"` substring). This
    preserves the historical "Drift in column 'X'" wording for non-GroupBy
    reports — no surprise behavior change for existing users.
  • `_render` now accepts an optional `display_name=` argument and uses it as
    the counter header.

Reproduce BEFORE/AFTER yourself (copy-paste)

```bash
git fetch origin && git fetch https://github.com/jbbqqf/evidently.git fix/1706-groupby-valuedrift-display-name:_pr1706
pip install -q -e ".[dev]" >/dev/null

run_check() {
python - <<'PY'
import numpy as np, pandas as pd
from evidently.core.datasets import Dataset, DataDefinition
from evidently.core.report import Report
from evidently.metrics.column_statistics import ValueDrift
from evidently.metrics.group_by import GroupBy
rng = np.random.default_rng(0)
df = pd.DataFrame({
"value": np.concatenate([rng.normal(size=100), rng.normal(loc=2, size=100)]),
"group": ["a"]*100 + ["b"]*100,
})
ref = Dataset.from_pandas(df, data_definition=DataDefinition())
cur = Dataset.from_pandas(df.copy(), data_definition=DataDefinition())
snap = Report([GroupBy(ValueDrift(column="value"), "group")]).run(cur, ref)
ctx = snap.context
for fp in snap.metric_results:
res = ctx.get_metric_result(fp)
widgets = res.widget if isinstance(res.widget, list) else [res.widget]
for w in widgets:
for c in (w.dict().get("params") or {}).get("counters") or []:
print("widget title:", c.get("value"))
PY
}

BEFORE — origin/main: every counter says 'Drift in column 'value'', no group/label suffix.

git checkout origin/main -- src/evidently/metrics/column_statistics.py
run_check

Expected: 'widget title: Drift in column \'value\'' (twice).

AFTER — this branch: each widget shows the GroupBy decoration.

git checkout _pr1706 -- src/evidently/metrics/column_statistics.py
run_check

Expected: 'widget title: Value drift for value group by \'group\' for label: \'a\'' and same for label 'b'.

git checkout origin/main -- src/evidently/metrics/column_statistics.py
```

What I ran locally

  • `pytest tests/future/metrics tests/test_preset/test_data_drift_preset.py -q` -> 1417 passed.
  • `pytest tests/future/metrics/test_groupby_value_drift.py` -> 2 passed; on
    `origin/main` the GroupBy assertion fails with the bare "Drift in column 'value'"
    title.
  • `ruff check` and `ruff format --check` -> clean.

Edge cases

Scenario Before After
Plain `ValueDrift(column="x")` "Drift in column 'x'" unchanged
`GroupBy(ValueDrift(column="x"), "g")` "Drift in column 'x'" (bug) "Value drift for x group by 'g' for label: '<label>'"
`GroupBy(MaxValue("x"), "g")` (other metric) already correct unchanged

AI disclosure

This pull request was authored with assistance from Anthropic's Claude (an AI
coding assistant) running under my direction. I traced the patching mechanism
(`metrics/group_by.py:_patched_display_name`) and confirmed the fix matches
the convention StatisticsCalculation already uses.

…evidentlyai#1706)

ValueDriftCalculation._render hard-coded the widget title as
"Drift in column 'X'", ignoring whatever display_name had been
patched onto the calculation. As a result, GroupBy(ValueDrift(...))
widgets always rendered the bare column name and dropped the
"group by '<col>' for label: '<label>'" suffix that GroupBy adds for
every other metric (MaxValue/MeanValue/etc which go through
StatisticsCalculation.calculate and use self.display_name() at render
time).

Pass display_name through to _render and use it as the widget header
when it carries the GroupBy decoration; keep the historical wording
otherwise so non-GroupBy reports are unchanged. Add a regression test
that walks the rendered widget params for both shapes.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

GroupBy(ValueDrift) display_name not shown properly

1 participant