Skip to content

Add plot_scatter3d() and interactive_scatter3d() function pair#30

Merged
soumyaray merged 4 commits into
developfrom
feature-interactive-plot3d
May 11, 2026
Merged

Add plot_scatter3d() and interactive_scatter3d() function pair#30
soumyaray merged 4 commits into
developfrom
feature-interactive-plot3d

Conversation

@soumyaray
Copy link
Copy Markdown
Owner

@soumyaray soumyaray commented May 11, 2026

Summary

  • Adds a 3D scatterplot pair — plot_scatter3d() (returns a rotatable plotly htmlwidget) and interactive_scatter3d() (Shiny gadget). Both support optional colour mapping, aspect-ratio control, marker opacity/size, custom axis titles, and an explicit camera argument for reproducing a specific view.
  • The gadget accepts every plot_scatter3d() argument as a starting value, captures the live 3D camera via plotly_relayout, and cat()s a reproducible plot_scatter3d(...) call on Done — so do.call(plot_scatter3d, result) finalises the view for an Rmd and do.call(interactive_scatter3d, result) resumes the session. Camera state is re-passed into every render (read with shiny::isolate()) so structural changes like a colour toggle don't reset the view.
  • Internal validators (numeric-column listing, "≥ 3 numeric" guard, scalar/list style checks, axis-arg type-check with a helpful unquoted-identifier error) live in R/scatter3d_helpers.R and are shared by both functions. plotly added to Imports. Unit tests cover plot_scatter3d() end-to-end via TDD red-green-refactor; the gadget is manually verified per the package convention.

Three new entries in docs/future-work.md seed deferred items: package-wide NSE column references, non-numeric axis support, and a richer bundled teaching dataset to replace moderation_data as the default for multiple functions.

Test plan

  • devtools::test() — all green (incl. 12 new plot_scatter3d() tests)
  • devtools::check() — 0 errors / 0 warnings (5 pre-existing notes, none from new code)
  • devtools::run_examples() — all plot_scatter3d() examples run without launching a viewer
  • interactive_scatter3d(moderation_data) opens in RStudio Viewer; column pickers and sliders update the plot live
  • Rotation/zoom persists across slider, picker, and colour-toggle changes
  • Done prints a copy-pasteable plot_scatter3d(...) call including the captured camera; pasting it reproduces the same view
  • do.call(interactive_scatter3d, result) resumes the captured session (same columns, sliders, camera, titles)
  • Cancel returns NULL with no console output
  • plot_scatter3d() and interactive_scatter3d() error clearly when data has fewer than 3 numeric columns
  • plot_scatter3d(df, x=x, ...) shows the "must be a character column name" hint instead of R's default "object 'x' not found"

soumyaray added 4 commits May 11, 2026 21:59
- Add Rplots.pdf to .gitignore; it's a transient artifact produced by
  R's default graphics device when base plot() runs in non-interactive
  contexts (Rscript, devtools::test, devtools::run_examples,
  R CMD check). tests/testthat/test-plots.R already does an explicit
  unlink() but example runs don't, so the file kept showing up
  untracked.
- Set MD024 (no-duplicate-headings) to siblings_only in
  .markdownlint.json so repeated subheadings under different parents
  (e.g. each future-work entry having its own "### Motivation") are
  accepted.
A new 3D scatterplot pair for visualising three numeric columns of a
data frame, mirroring the existing function-pair convention.

plot_scatter3d() returns a rotatable plotly htmlwidget with optional
colour mapping, aspect-ratio control, marker opacity/size, custom axis
titles, and an explicit camera argument for reproducing a specific
view. Numeric-only contract on x/y/z axes; categorical separation goes
through `color`. When x/y/z are NULL the first three numeric columns
are auto-picked (silent for exactly-three, one-line message for more).

interactive_scatter3d() wraps it as a Shiny gadget with column pickers
(x/y/z/color) and display sliders (aspect, opacity, size). User-driven
rotation and zoom are captured via the plotly_relayout event and
re-passed into every render (read with shiny::isolate() to avoid a
re-render loop) so structural changes like a colour toggle don't reset
the view. Accepts every plot_scatter3d() argument as a starting value,
so do.call(interactive_scatter3d, prior_result) resumes a captured
session. On Done, cat()s a reproducible plot_scatter3d() call to the
console -- including the captured camera -- and returns the args list
invisibly so do.call(plot_scatter3d, result) finalises the view. On
Cancel, returns NULL.

Internal validators (numeric-column listing, "3 numeric columns
required" guard, scalar/list style checks, axis-arg type-check with a
helpful unquoted-identifier error message) live in
R/scatter3d_helpers.R and are shared between the two functions.

Adds plotly to DESCRIPTION Imports. Unit tests cover plot_scatter3d()
end-to-end (TDD red-green-refactor for each behaviour); the gadget is
manually verified per package convention.
- Add a "3D Scatterplots" section to README.Rmd describing
  interactive_scatter3d() and plot_scatter3d(), then regenerate
  README.md via devtools::build_readme().
- docs/future-work.md grows three new entries seeded by design
  decisions made during this branch:
  - Accept string + NSE column references across model-relevant
    functions (Q1 of the scatter3d plan deferred NSE; this is the
    package-wide sweep entry).
  - Non-numeric axis support on plot_scatter3d() (Date / POSIXct /
    factor) -- v1 enforces numeric-only; this is the eventual
    relaxation entry.
  - A real bundled teaching dataset to replace / augment
    moderation_data as more functions default to it.
- Workflow at .github/workflows/R-CMD-check.yaml runs R CMD check on
  macOS-release, Windows-release, and Ubuntu-release. Slimmed from
  the standard r-lib check-standard template (no Ubuntu devel or
  oldrel-1) — most users are on mac / Windows, and a single
  Ubuntu-release job is enough to catch Linux-specific issues the
  macOS dev environment hides. Triggers on push to main / develop
  and on every pull request.
- Adds the R-CMD-check badge between the existing badges markers in
  README.Rmd; regenerates README.md via devtools::build_readme().
- Extends .Rbuildignore to exclude .github (CI config), .git,
  .mailmap, LICENSE.md, and data-raw from the package build. .github
  is new in this branch; the other four silence pre-existing R CMD
  check NOTEs ("hidden files" and "non-standard top-level files").
  Local check now reports 3 NOTEs instead of 5.
@soumyaray soumyaray force-pushed the feature-interactive-plot3d branch from 9cfd2fe to 4957f70 Compare May 11, 2026 14:14
@soumyaray soumyaray merged commit 04d8f74 into develop May 11, 2026
3 checks passed
@soumyaray soumyaray deleted the feature-interactive-plot3d branch May 11, 2026 14:46
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.

1 participant