Skip to content

Commit 3c069a5

Browse files
committed
fix(draw_batch): Extend subframe resolution to draw_batch()
Follow-up to BUG_AliasDataFrame_20260324_draw_subframe_resolution. draw_batch() bypassed draw() and called dfdraw directly, missing the Subframe.column resolution. Same fix applied: detect patterns across all specs, materialize as temporary columns, rewrite expressions. 1378 passed, 6 failed (pre-existing), no regressions.
1 parent 9a9d9ba commit 3c069a5

1 file changed

Lines changed: 55 additions & 1 deletion

File tree

UTILS/dfextensions/AliasDataFrame/AliasDataFrame.py

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10305,8 +10305,62 @@ def draw_batch(self,
1030510305
print(f"Materializing {len(to_materialize)} aliases: {sorted(to_materialize)}")
1030610306
self.materialize_aliases(names=list(to_materialize))
1030710307

10308+
# =================================================================
10309+
# Subframe column resolution for draw_batch
10310+
# Same logic as draw() — detect Subframe.column patterns across
10311+
# all specs, materialize as temporary columns, rewrite expressions.
10312+
# =================================================================
10313+
subframe_replacements = {}
10314+
df_for_plot = self.df
10315+
if hasattr(self, '_subframes') and hasattr(self._subframes, 'subframes'):
10316+
sf_names = set(self._subframes.subframes.keys())
10317+
merged_defaults = {**(defaults or {}), **kwargs}
10318+
10319+
# Collect all text across all specs
10320+
all_text_parts = []
10321+
for name, spec in specs.items():
10322+
merged_spec = {**merged_defaults, **spec}
10323+
all_text_parts.append(merged_spec.get('expr', name))
10324+
if merged_spec.get('selection'):
10325+
all_text_parts.append(merged_spec['selection'])
10326+
if merged_spec.get('group_by'):
10327+
all_text_parts.append(str(merged_spec['group_by']))
10328+
all_text = ' '.join(all_text_parts)
10329+
10330+
import re as _re
10331+
for match in _re.finditer(r'\b(\w+)\.(\w+)\b', all_text):
10332+
sf_name, col_name = match.group(1), match.group(2)
10333+
if sf_name in sf_names:
10334+
dot_ref = f"{sf_name}.{col_name}"
10335+
flat_ref = f"{sf_name}_{col_name}"
10336+
if flat_ref not in df_for_plot.columns and dot_ref not in subframe_replacements:
10337+
try:
10338+
sf = self.get_subframe(sf_name)
10339+
index_cols = self._subframes.get_entry(sf_name)['index']
10340+
if isinstance(index_cols, str):
10341+
index_cols = [index_cols]
10342+
join_idx, missing = self._compute_join_indices(sf_name, index_cols)
10343+
if col_name in sf.df.columns:
10344+
if df_for_plot is self.df:
10345+
df_for_plot = df_for_plot.copy()
10346+
df_for_plot[flat_ref] = sf.df[col_name].values[join_idx]
10347+
subframe_replacements[dot_ref] = flat_ref
10348+
except Exception:
10349+
pass
10350+
10351+
# Rewrite all specs: replace Sub.col → Sub_col
10352+
if subframe_replacements:
10353+
for name, spec in specs.items():
10354+
for dot_ref, flat_ref in subframe_replacements.items():
10355+
if 'expr' in spec:
10356+
spec['expr'] = spec['expr'].replace(dot_ref, flat_ref)
10357+
if 'selection' in spec and spec['selection']:
10358+
spec['selection'] = spec['selection'].replace(dot_ref, flat_ref)
10359+
if 'group_by' in spec and isinstance(spec.get('group_by'), str):
10360+
spec['group_by'] = spec['group_by'].replace(dot_ref, flat_ref)
10361+
1030810362
# Delegate to dfdraw batch
10309-
plotter = DFDraw(self.df)
10363+
plotter = DFDraw(df_for_plot)
1031010364
plotter._data_source = self # For duck-typed axis title lookup
1031110365

1031210366
results = plotter.draw_batch(

0 commit comments

Comments
 (0)