build_tools.syllable_analysis.plotting.interactive
==================================================
.. py:module:: build_tools.syllable_analysis.plotting.interactive
.. autoapi-nested-parse::
Interactive Plotly visualizations for analysis tools.
This module provides Plotly-based interactive plotting functions for dimensionality
reduction visualizations. Functions create standalone HTML files with zoom, pan,
hover, and export capabilities.
Plotly is an optional dependency. If not installed, functions will raise ImportError
with installation instructions.
Usage Example
-------------
::
import numpy as np
from pathlib import Path
from build_tools.syllable_analysis.plotting.interactive import (
create_interactive_scatter,
save_interactive_html,
PLOTLY_AVAILABLE
)
if not PLOTLY_AVAILABLE:
print("Plotly not installed - skipping interactive visualization")
else:
# Create visualization
records = [
{"syllable": "ka", "frequency": 100, "features": {...}},
...
]
tsne_coords = np.array([[...], [...]])
fig = create_interactive_scatter(records, tsne_coords)
# Save to HTML
output_path = Path("_working/output.html")
save_interactive_html(fig, output_path, perplexity=30, random_state=42)
Attributes
----------
.. autoapisummary::
build_tools.syllable_analysis.plotting.interactive.PLOTLY_AVAILABLE
Functions
---------
.. autoapisummary::
build_tools.syllable_analysis.plotting.interactive.create_interactive_scatter
build_tools.syllable_analysis.plotting.interactive.build_hover_text
build_tools.syllable_analysis.plotting.interactive.save_interactive_html
build_tools.syllable_analysis.plotting.interactive.inject_responsive_css
build_tools.syllable_analysis.plotting.interactive.create_metadata_footer
Module Contents
---------------
.. py:data:: PLOTLY_AVAILABLE
:value: True
.. py:function:: create_interactive_scatter(records, tsne_coords, title = 't-SNE: Feature Signature Space (Interactive)')
Create interactive Plotly scatter plot of t-SNE coordinates.
Generates an interactive HTML-compatible visualization with rich hover tooltips,
zoom/pan controls, and export capabilities. Points are sized (log scale) and
colored by frequency.
:param records: List of annotated syllable records. Each must contain:
- syllable (str): Syllable text
- frequency (int): Occurrence count
- features (dict): Boolean feature flags (12 features)
:param tsne_coords: 2D coordinate array of shape (n_samples, 2) from t-SNE
:param title: Plot title (default: "t-SNE: Feature Signature Space (Interactive)")
:returns: Plotly Figure object with configured interactive scatter plot
:raises ImportError: If Plotly is not installed
:raises ValueError: If inputs are invalid or lengths don't match
.. admonition:: Example
>>> records = [
... {"syllable": "ka", "frequency": 100, "features": {"contains_plosive": True}},
... {"syllable": "mi", "frequency": 50, "features": {"contains_nasal": True}},
... ]
>>> coords = np.array([[1.0, 2.0], [3.0, 4.0]])
>>> fig = create_interactive_scatter(records, coords)
>>> fig.show() # Opens in browser
.. admonition:: Notes
- Point size uses log1p scale for better visibility across frequency ranges
- Hover text shows syllable, frequency, feature count, and up to 4 features
- If more than 4 features, shows "...+N more" truncation
- Viridis colorscale provides perceptually uniform coloring
- Fixed height (900px) with responsive width for consistent aspect ratio
- Plotly CDN used when saving to HTML for smaller file size
.. py:function:: build_hover_text(record, max_features = 4)
Build rich hover text for a single syllable record.
Creates HTML-formatted hover text showing syllable details, frequency,
and active features. Features are truncated if more than max_features
are present.
:param record: Syllable record with 'syllable', 'frequency', 'features' keys
:param max_features: Maximum features to show before truncating (default: 4)
:returns: HTML-formatted hover text string
.. admonition:: Example
>>> record = {
... "syllable": "kran",
... "frequency": 150,
... "features": {
... "contains_plosive": True,
... "contains_liquid": True,
... "contains_nasal": True,
... "starts_with_cluster": True,
... "ends_with_nasal": True,
... }
... }
>>> text = build_hover_text(record, max_features=4)
>>> print(text)
kran
Frequency: 150
Features: 5/12
contains_plosive, ...
...
.. admonition:: Notes
- Syllable shown in bold
- Frequency shown with comma separators (e.g., "1,234")
- Feature count shows active/total (e.g., "5/12")
- First N features shown in italics
- If more than N features, shows "+M more" truncation message
.. py:function:: save_interactive_html(fig, output_path, perplexity, random_state, min_width = DEFAULT_PLOT_MIN_WIDTH)
Save interactive Plotly figure as standalone HTML.
Creates a self-contained HTML file with embedded Plotly visualization that can be:
- Opened directly in any web browser
- Shared with collaborators
- Embedded in reports or documentation
- Explored with zoom, pan, hover, and export controls
The HTML file uses Plotly CDN for JavaScript dependencies (smaller file size)
and includes responsive CSS and a metadata footer.
:param fig: Plotly Figure object from create_interactive_scatter()
:param output_path: Output HTML file path (parent directory must exist)
:param perplexity: t-SNE perplexity parameter (for metadata footer)
:param random_state: Random seed used (for metadata footer)
:param min_width: Minimum width constraint in pixels (default: 1250)
:raises ImportError: If Plotly is not installed
:raises FileNotFoundError: If parent directory doesn't exist
:raises ValueError: If output_path doesn't end with .html
.. admonition:: Example
>>> fig = create_interactive_scatter(records, tsne_coords)
>>> output_path = Path("_working/visualization.html")
>>> save_interactive_html(fig, output_path, perplexity=30, random_state=42)
.. admonition:: Notes
- Plotly CDN used for smaller file size vs. full JS bundle
- Mode bar configured with additional tools (hoverclosest, hovercompare)
- Export to PNG button configured for high-resolution (1600x1200, 2x scale)
- Responsive CSS ensures minimum width of 1250px
- Metadata footer includes algorithm parameters and generation time
.. py:function:: inject_responsive_css(html_content, min_width = DEFAULT_PLOT_MIN_WIDTH)
Inject responsive CSS into HTML content.
Adds CSS rules to ensure the plot has a minimum width and proper scrolling
behavior. This prevents the plot from becoming too narrow on small screens
while allowing horizontal scrolling when necessary.
:param html_content: Original HTML content from Plotly
:param min_width: Minimum width constraint in pixels (default: 1250)
:returns: HTML content with injected CSS in