Skip to content

Allow symlog to be adjusted for region of linearity #39

Merged
Demonstrandum merged 14 commits into
masterfrom
cursor/tensorbored-package-structure-8d17
Feb 16, 2026
Merged

Allow symlog to be adjusted for region of linearity #39
Demonstrandum merged 14 commits into
masterfrom
cursor/tensorbored-package-structure-8d17

Conversation

@Demonstrandum

Copy link
Copy Markdown
Owner

Motivation for features / changes

This PR addresses issue #34, allowing users to configure the linear threshold for the symmetric log (SYMLOG10) scale. Previously, the SYMLOG10 scale used a fixed linear region for |x| < 1. This change introduces a linearThreshold parameter c, making the scale approximately linear for |x| < c. This provides greater flexibility for visualizing data with varying magnitudes near zero.

Technical description of changes

  1. Core Scale Logic: Modified SymLog10Scale and createScale in scale.ts to accept a linearThreshold parameter (default 1). The transformation formula is updated to sign(x) * log10(|x|/c + 1). The legacy symlog-scale.ts was also updated for consistency.
  2. State Management: Added symlogLinearThreshold to MetricsSettings, METRICS_SETTINGS_DEFAULT, and introduced a new action metricsChangeSymlogLinearThreshold. Reducers and selectors were updated to manage this new setting.
  3. Settings Pane UI: A new "Symlog Linear Threshold" numeric input was added to the Scalars section of the settings pane, allowing users to adjust the value. Corresponding container, component, template, and SCSS changes were implemented.
  4. Component Threading: The symlogLinearThreshold input was threaded through LineChartComponent, ScalarCardComponent, ScalarCardContainer, SuperimposedCardComponent, and SuperimposedCardContainer to ensure the setting is applied to all relevant charts.
  5. Persistence: symlogLinearThreshold was added to BackendSettings and PersistableSettings interfaces, and serialization/deserialization logic was updated in persistent_settings_data_source.ts to ensure the setting persists across sessions.
  6. Profile System: symlogLinearThreshold was added to ProfileData and createEmptyProfile. Profile effects were updated to save and restore this setting when profiles are activated or saved. The Python profile_writer.py was also updated to accept symlog_linear_threshold.
  7. Tests: Added new test cases in scale_test.ts to verify the behavior of SymLog10Scale with custom linearThreshold values, including forward/reverse consistency, linear region behavior, niceDomain, and ticks.
  8. Documentation: Updated AGENTS_DEV.md to reflect the new feature and its usage.

Screenshots of UI changes (or N/A)

A new "Symlog Linear Threshold" input field has been added to the "Scalars" section of the settings pane.

Detailed steps to verify changes work correctly (as executed by you)

  1. Verify UI Control: Open TensorBoard, navigate to the settings pane, and locate the "Symlog Linear Threshold" input under "Scalars". Change the value and observe its effect on charts using the SYMLOG10 scale.
  2. Verify Persistence: Change the symlogLinearThreshold in the UI, then refresh the page or close/reopen TensorBoard. Confirm the setting is retained.
  3. Verify Profile Integration:
    • Create a profile with a custom symlogLinearThreshold.
    • Activate the profile and verify the threshold is applied.
    • Save the profile and confirm the symlogLinearThreshold is included in the saved profile data.
  4. Verify Scale Behavior:
    • Generate data with values both very close to zero and large values.
    • Set a chart to use SYMLOG10 scale.
    • Adjust the symlogLinearThreshold (e.g., 0.1, 1, 10) and observe how the linear region near zero changes, making small values more or less spread out.
  5. Run Unit Tests: Execute npm test to ensure all existing and new scale tests pass, specifically checking the symlog10 with custom linearThreshold suite.

Alternate designs / implementations considered (or N/A)

N/A


Open in Cursor Open in Web

@cursor

cursor Bot commented Feb 10, 2026

Copy link
Copy Markdown

Cursor Agent can help with this pull request. Just @cursor in comments and I'll start working on changes in this branch.
Learn more about Cursor Agents

@Demonstrandum Demonstrandum changed the title Tensorbored package structure Allow symlog to be adjusted for region of linearity Feb 10, 2026
@Demonstrandum Demonstrandum marked this pull request as ready for review February 10, 2026 17:02
@cursor cursor Bot force-pushed the cursor/tensorbored-package-structure-8d17 branch from 9684016 to 654b7e4 Compare February 10, 2026 17:40
@github-actions

github-actions Bot commented Feb 10, 2026

Copy link
Copy Markdown

Preview Deployment

Status ✅ Running
Live Preview https://Demonstrandum-tensorbored-pr-39.hf.space
Space https://huggingface.co/spaces/Demonstrandum/tensorbored-pr-39
Details
  • Wheel: tensorbored_nightly-2.21.0a20260216-py3-none-any.whl
  • Commit: 7d31fee
  • Build status: success

cursoragent and others added 10 commits February 12, 2026 15:38
Add a symlogLinearThreshold parameter to the symmetric log scale that
controls the width of the linear region near zero. The formula changes
from sign(x) * log10(|x| + 1) to sign(x) * log10(|x|/c + 1), where
c is the threshold.

- c = 1 (default): linear near |x| < 1 (current behavior)
- c = 10: linear near |x| < 10
- c = 0.01: linear near |x| < 0.01

Changes:
- Scale layer: SymLog10Scale accepts linearThreshold in constructor
- createScale() accepts optional symlogLinearThreshold parameter
- MetricsSettings: new symlogLinearThreshold field (default 1)
- Action: metricsChangeSymlogLinearThreshold
- Reducer/Selector: handle the new setting
- Settings pane: numeric input for the threshold
- LineChartComponent: new symlogLinearThreshold input, rebuilds scales
- Scalar card: threads threshold from store → container → component → chart
- Superimposed card: threads threshold similarly
- Legacy symlog-scale.ts: updated for consistency
- PersistableSettings: threshold persisted to backend settings
- Scale tests: new test suite for custom threshold values

Closes #34

Co-authored-by: Samuel <samuel@knutsen.co>
- Add symlogLinearThreshold field to ProfileData interface
- Include threshold in profile save/load effects
- Pass threshold when activating profiles
- Add symlog_linear_threshold param to Python profile_writer
- Update profileMetricsSettingsApplied action to carry threshold

Co-authored-by: Samuel <samuel@knutsen.co>
Ensure the threshold is properly serialized to/from backend settings
storage (localStorage) via OSSSettingsConverter.

Co-authored-by: Samuel <samuel@knutsen.co>
Co-authored-by: Samuel <samuel@knutsen.co>
…nent

Co-authored-by: Samuel <samuel@knutsen.co>
…rofile effects

Only set symlogLinearThreshold on the action payload when the profile
field is defined, avoiding passing undefined to an optional property
which violates exactOptionalPropertyTypes.

Co-authored-by: Samuel <samuel@knutsen.co>
…lStorage survival

Co-authored-by: Samuel <samuel@knutsen.co>
Each scalar card and superimposed card now has a 'Symlog threshold'
submenu in the overflow menu (three-dot icon). Users can type a
per-card threshold value, or reset to use the global default.

The menu shows the current effective value with an asterisk (*) when
a per-card override is active. The 'Reset to global' button clears
the override.

This follows the same local-state pattern as yScaleType and
xScaleTypeOverride — per-card state lives on the component instance.

Co-authored-by: Samuel <samuel@knutsen.co>
@cursor cursor Bot force-pushed the cursor/tensorbored-package-structure-8d17 branch from 6867ef8 to d1e435d Compare February 12, 2026 15:46
cursoragent and others added 4 commits February 16, 2026 11:21
…rofiles

Replace the local component-state symlogLinearThresholdOverride with a
fully store-backed per-tag system that mirrors how tagAxisScales works:

- MetricsNonNamespacedState: new tagSymlogLinearThresholds record
- Action: metricsTagSymlogLinearThresholdChanged (tag + threshold)
- Reducer: updates tagSymlogLinearThresholds record
- Selectors: getTagSymlogLinearThresholds, getEffectiveTagSymlogLinearThreshold(tag)
- localStorage: extends StoredAxisScalesV1 with symlogLinearThreshold
  and tagSymlogLinearThresholds fields, persisted alongside axis scales
- Containers: select getEffectiveTagSymlogLinearThreshold(tag) per card,
  dispatch metricsTagSymlogLinearThresholdChanged on user input
- Components: emit @output() instead of mutating local state
- Profile types: tagSymlogLinearThresholds field on ProfileData
- Profile effects: save/load per-tag thresholds with profiles
- Python profile_writer: tag_symlog_linear_thresholds parameter

Co-authored-by: Samuel <samuel@knutsen.co>
…ard_container

Co-authored-by: Samuel <samuel@knutsen.co>
Co-authored-by: Samuel <samuel@knutsen.co>
@Demonstrandum Demonstrandum merged commit 2a90181 into master Feb 16, 2026
13 checks passed
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.

Symlog should let you specify what region we transition to being linear

2 participants