Skip to content

Fix: expose widget_type and widget_location in hvplot params. Fixes #… - #2069

Open
Vamshi1404 wants to merge 3 commits into
holoviz:mainfrom
Vamshi1404:fix/1915-expose-widget-type-widget-location
Open

Fix: expose widget_type and widget_location in hvplot params. Fixes #…#2069
Vamshi1404 wants to merge 3 commits into
holoviz:mainfrom
Vamshi1404:fix/1915-expose-widget-type-widget-location

Conversation

@Vamshi1404

@Vamshi1404 Vamshi1404 commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

Description

Fixes #1915

This PR exposes widget_type and widget_location as declared parameter attributes on hvPlotBaseView, which is shared by both hvPlotView and hvPlotUIView. These parameters are forwarded through hvPlotView.get_plot to the underlying .hvplot(...) call, mirroring the existing groupby forwarding behavior.

Both parameters default to None, so existing behavior remains unchanged when they are not specified.

This enables spec-based (type: hvplot) plots to control the groupby widget. For example, a scrubber/player can be placed at the bottom:

sources:
  widget_source:
    type: file
    tables:
      widget_table: widget_test_data.csv

layouts:
  - title: Widget Type Test
    views:
      - type: hvplot
        kind: line
        x: year
        y: value
        groupby: region
        widget_type: scrubber
        widget_location: bottom

Tests

Tests were added in lumen/tests/views/test_hvplot_datashade.py:

  • test_widget_params_declared — verifies that both parameters exist on hvPlotBaseView, which is used by the AI agent schema.
  • test_hvplot_view_forwards_widget_params — verifies that widget_type, widget_location, and groupby are correctly forwarded to .hvplot().
  • test_hvplot_view_omits_unset_widget_params — verifies that unset widget parameters are not passed, preserving existing behavior.

Verification

  • lumen/tests/views/: 83 passed, 11 skipped
  • Full test suite: 2539 passed, 304 skipped, 17 failed
  • The 17 full-suite failures are pre-existing and unrelated to this change. They reproduce identically on main and are related to LLM routing, xarray zarr dtype, and the xarray upload handler.
  • ruff check passes on both modified files.

Known Limitation

The chat/AI path (lumen-ai) routes through hvPlotUIView, which uses hvPlot's explorer (hvDataFrameExplorer/hvGridExplorer). These explorers currently hard-code their internal pn.pane.HoloViews pane with widget_location='bottom' and do not accept widget_type.

As a result, although widget_type and widget_location are valid parameters on hvPlotUIView, they are not currently applied in the chat window.

Supporting the scrubber in the chat path will require a follow-up change to hvPlot's explorer and additional forwarding from hvPlotUIView.

AI Disclosure

Tool & Model: Cursor + Claude (opencode assistant)

Usage:

Drafted the parameter additions, wired the forwarding in hvPlotView.get_plot, and wrote the new tests. The changes were validated by reproducing the full test suite and running ruff locally.

  • I have tested all AI-generated content in my PR.
  • I take responsibility for all AI-generated content in my PR.

Checklist

  • Tests added and are passing
  • Added documentation

@codecov

codecov Bot commented Aug 28, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 75.95%. Comparing base (0d13533) to head (b9a74bf).

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2069      +/-   ##
==========================================
+ Coverage   75.93%   75.95%   +0.01%     
==========================================
  Files         215      215              
  Lines       40191    40211      +20     
==========================================
+ Hits        30521    30542      +21     
+ Misses       9670     9669       -1     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@Vamshi1404

Copy link
Copy Markdown
Contributor Author

@ahuang11 When you pointed at the IndicatorView / _get_params region and asked to add widget_type and widget_location, were you referring to the hvPlotBaseView param declarations (where groupby lives, right below IndicatorView)? If so, that's already addressed and pushed: both are declared as param attributes on hvPlotBaseView and forwarded through hvPlotView.get_plot to .hvplot(). Or did you specifically want these params added to the IndicatorView class itself — could you clarify so I make the right change?"

@ghostiee-11

ghostiee-11 commented Aug 28, 2026

Copy link
Copy Markdown
Collaborator

Thanks for picking this up!!
Can you please run Lumen AI and then show me the video of this working :)

@Vamshi1404

Copy link
Copy Markdown
Contributor Author
Video.Project.mp4

Live demo of the new widget_type / widget_location params on Lumen's hvPlotView (grouped data + scrubber widget). This dashboard is driven entirely by a declarative YAML spec (demo_widget.yaml) served as a standalone Lumen dashboard — python -m lumen serve demo_widget.yaml. It is not wired to the chat interface; this is the plain classic-dashboard rendering path.

Data: synthetic daily timeseries (demo_data.csv) — 1,096 rows spanning 2024-01-01 to 2026-12-31. Columns: time, value (a synthetic seasonal + trend + noise signal, rounded to 2 decimals), year, month. The plot groups by [year, month] and the scrubber steps through each year/month frame.

@Vamshi1404

Vamshi1404 commented Aug 28, 2026

Copy link
Copy Markdown
Contributor Author

Question: widget_type / widget_location (#1915)

The parameters work correctly through the classic declarative path. hvPlotView.get_plot forwards them to df.hvplot(...) in lumen/views/base.py:1321-1324, and the scrubber Player renders correctly (with a small get_panel fix to handle the Row/Column returned by Panel).

However, the AI/chat path currently appears to silently ignore these parameters.

hvPlotAgent renders hvPlotUIView (lumen/ai/agents/hvplot.py:38,99), which builds an hvPlotExplorer. Its _get_args only forwards parameters declared by the explorer, Colormapping, or Operations (lumen/views/base.py:1158-1163).

Since the hvplot 0.11.3 explorer supports groupby/by but not widget_type/widget_location, a model-requested scrubber is therefore dropped without an error.

Question

Given that the project has shifted toward the AI interface, what would be the preferred behavior going forward?

  1. Route scrubber/animated requests to the classic hvPlotView when widget_type or widget_location is present.
  2. Extend hvPlotExplorer to support these parameters.
  3. Keep them limited to classic YAML/declarative dashboards and treat them as unsupported in the AI interface.

Would appreciate guidance on which direction best fits the current architecture.

@ghostiee-11

Copy link
Copy Markdown
Collaborator

Make the video on lumen ai serve actual platform instead of probe

@Vamshi1404

Copy link
Copy Markdown
Contributor Author

Status update on getting the scrubber working through the actual chat interface (not just
the classic YAML dashboard path): the widget_type/widget_location params themselves are
correct and get forwarded properly — confirmed via hvPlotAgent with a real model, real
retry loop, no mocking. But two pre-existing bugs, unrelated to this PR, make it unreliable
end-to-end through chat:

  1. aggregator: None fails validation even though None is a listed valid option.
    hvPlotAgent-generated specs set aggregator: None (a literal YAML string) whenever no
    further aggregation is needed on the data — which is common, not an edge case. The
    LLM-facing schema (built via parameter_to_field from param.Selector.get_range())
    represents "no aggregation" as the string 'None', but the runtime param only accepts
    the actual Python None singleton, so the two disagree and validation fails.

  2. When that validation error should trigger a retry-with-correction, the retry itself
    crashes.
    hvPlotAgent._get_model() requires a schema argument that the generic
    revise()/_invoke_prompt() call path (used for retries and explain()) doesn't pass —
    TypeError: hvPlotAgent._get_model() missing 1 required positional argument: 'schema'.
    So a recoverable validation error becomes a hard failure, because the model never gets
    the chance to see the error and self-correct.

Both are pre-existing on main (traced via git blame to #2035 and #1506 respectively),
not introduced by this PR. Confirmed bug 2 is the real blocker for bug 1 ever
self-resolving: in a headless test with a local fix that only removed the TypeError, the
retry loop ran successfully and the model corrected aggregator to a valid value ('any')
on its own — meaning the built-in error-recovery mechanism already works, it just never
gets to run.

Given the scope of this PR is widget_type/widget_location, I don't think either of
these belongs bundled into it. Planning to file them as separate issues (have full
diagnostic detail ready — repro steps, exact tracebacks, git blame evidence, suggested fix
directions for each). Let me know if you'd rather see one or both fixed here instead, or if
a headless proof-of-concept is enough for now with a follow-up video once those land
separately.

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.

Expose widget type in hvplot param

2 participants