Skip to content

canvod.viz API reference

2D and 3D hemispheric visualization tools.

Package

Visualization and plotting utilities for GNSS VOD data.

This package provides 2D and 3D visualization capabilities for hemispherical GNSS grids and VOD data, with both publication-quality (matplotlib) and interactive (plotly) rendering options.

Examples:

2D polar visualization::

from canvod.viz import HemisphereVisualizer2D
from canvod.grids import create_hemigrid

grid = create_hemigrid(grid_type='equal_area', angular_resolution=10.0)
viz = HemisphereVisualizer2D(grid)
fig, ax = viz.plot_grid_patches(data=vod_data, title="VOD Distribution")

Convenience function::

from canvod.viz import visualize_grid, add_tissot_indicatrix

fig, ax = visualize_grid(grid, data=vod_data, cmap='viridis')
add_tissot_indicatrix(ax, grid, n_sample=5)

3D interactive visualization::

from canvod.viz import HemisphereVisualizer3D

viz3d = HemisphereVisualizer3D(grid)
fig = viz3d.plot_hemisphere_surface(data=vod_data, title="Interactive VOD")
fig.show()

Unified API::

from canvod.viz import HemisphereVisualizer

viz = HemisphereVisualizer(grid)
fig_2d, ax_2d = viz.plot_2d(data=vod_data)
fig_3d = viz.plot_3d(data=vod_data)

HemisphereVisualizer

Unified hemisphere visualizer combining 2D and 3D capabilities.

Provides consistent API for both publication-quality matplotlib plots and interactive plotly visualizations. Handles styling coordination between different rendering backends.

Parameters:

Name Type Description Default
grid HemiGrid

Hemisphere grid to visualize

required

Examples:

Create both 2D and 3D visualizations::

from canvod.grids import create_hemigrid
from canvod.viz import HemisphereVisualizer

grid = create_hemigrid(grid_type='equal_area', angular_resolution=10.0)
viz = HemisphereVisualizer(grid)

# Publication-quality 2D plot
fig_2d, ax_2d = viz.plot_2d(
    data=vod_data,
    title="VOD Distribution",
    save_path="publication.png"
)

# Interactive 3D plot
fig_3d = viz.plot_3d(
    data=vod_data,
    title="Interactive VOD Explorer"
)
fig_3d.show()

Switch styles easily::

# Publication style
pub_style = create_publication_style()
viz.set_style(pub_style)
fig, ax = viz.plot_2d(data=vod_data)

# Interactive style
int_style = create_interactive_style(dark_mode=True)
viz.set_style(int_style)
fig = viz.plot_3d(data=vod_data)

__init__(grid)

Initialize unified visualizer.

Parameters:

Name Type Description Default
grid HemiGrid

Hemisphere grid to visualize

required

set_style(style)

Set unified styling for both 2D and 3D plots.

Parameters:

Name Type Description Default
style PlotStyle

Styling configuration

required

Examples:

>>> pub_style = create_publication_style()
>>> viz.set_style(pub_style)
>>> fig, ax = viz.plot_2d(data=vod_data)

plot_2d(data=None, title=None, ax=None, save_path=None, style=None, **kwargs)

Create 2D publication-quality plot.

Parameters:

Name Type Description Default
data ndarray

Data values per cell

None
title str

Plot title

None
ax Axes

Existing axes to plot on

None
save_path Path or str

Save figure to this path

None
style PolarPlotStyle

Override default 2D style

None
**kwargs Any

Additional styling parameters

{}

Returns:

Name Type Description
fig Figure

Figure object

ax Axes

Polar axes with plot

Examples:

>>> fig, ax = viz.plot_2d(
...     data=vod_data,
...     title="VOD Distribution",
...     cmap='plasma',
...     save_path="output.png",
...     dpi=300
... )

plot_3d(data=None, title=None, style=None, **kwargs)

Create 3D interactive plot.

Parameters:

Name Type Description Default
data ndarray

Data values per cell

None
title str

Plot title

None
style PlotStyle

Override default 3D style

None
**kwargs Any

Additional plotly parameters

{}

Returns:

Type Description
Figure

Interactive 3D figure

Examples:

>>> fig = viz.plot_3d(
...     data=vod_data,
...     title="Interactive VOD",
...     opacity=0.9,
...     width=1000,
...     height=800
... )
>>> fig.show()
>>> fig.write_html("interactive.html")

plot_3d_mesh(data=None, title=None, **kwargs)

Create 3D mesh plot showing cell boundaries.

Parameters:

Name Type Description Default
data ndarray

Data values per cell

None
title str

Plot title

None
**kwargs Any

Additional plotly parameters

{}

Returns:

Type Description
Figure

Interactive mesh figure

Examples:

>>> fig = viz.plot_3d_mesh(
...     data=vod_data,
...     title="VOD Mesh View",
...     opacity=0.7
... )

create_comparison_plot(data=None, title_2d='2D Polar View', title_3d='3D Hemisphere View', save_2d=None, save_3d=None)

Create both 2D and 3D plots for comparison.

Parameters:

Name Type Description Default
data ndarray

Data values per cell

None
title_2d str

Title for 2D plot

"2D Polar View"
title_3d str

Title for 3D plot

"3D Hemisphere View"
save_2d Path or str

Save 2D figure to this path

None
save_3d Path or str

Save 3D figure to this path (HTML)

None

Returns:

Name Type Description
plot_2d tuple of Figure and Axes

2D matplotlib plot

plot_3d Figure

3D plotly plot

Examples:

>>> (fig_2d, ax_2d), fig_3d = viz.create_comparison_plot(
...     data=vod_data,
...     save_2d="comparison_2d.png",
...     save_3d="comparison_3d.html"
... )
>>> plt.show()  # Show 2D
>>> fig_3d.show()  # Show 3D

create_publication_figure(data=None, title='Hemispherical Data Distribution', save_path=None, dpi=300, **kwargs)

Create publication-ready figure with optimal styling.

Parameters:

Name Type Description Default
data ndarray

Data values per cell

None
title str

Plot title

"Hemispherical Data Distribution"
save_path Path or str

Save figure to this path

None
dpi int

Resolution in dots per inch

300
**kwargs Any

Additional styling parameters

{}

Returns:

Name Type Description
fig Figure

Publication-ready figure

ax Axes

Styled polar axes

Examples:

>>> fig, ax = viz.create_publication_figure(
...     data=vod_data,
...     title="VOD Distribution Over ExampleSite Site",
...     save_path="paper_figure_3.png",
...     dpi=600
... )

create_interactive_explorer(data=None, title='Interactive Data Explorer', dark_mode=True, save_html=None)

Create interactive explorer with optimal settings.

Parameters:

Name Type Description Default
data ndarray

Data values per cell

None
title str

Plot title

"Interactive Data Explorer"
dark_mode bool

Use dark theme

True
save_html Path or str

Save HTML to this path

None

Returns:

Type Description
Figure

Interactive explorer figure

Examples:

>>> fig = viz.create_interactive_explorer(
...     data=vod_data,
...     title="VOD Explorer",
...     dark_mode=True,
...     save_html="explorer.html"
... )
>>> fig.show()

HemisphereVisualizer2D

2D hemisphere visualization using matplotlib.

Creates publication-quality polar projection plots of hemispherical grids. Supports multiple grid types and rendering methods.

Parameters:

Name Type Description Default
grid HemiGrid

Hemisphere grid to visualize

required

Examples:

>>> from canvod.grids import create_hemigrid
>>> from canvod.viz import HemisphereVisualizer2D
>>>
>>> grid = create_hemigrid(grid_type='equal_area', angular_resolution=10.0)
>>> viz = HemisphereVisualizer2D(grid)
>>> fig, ax = viz.plot_grid_patches(data=vod_data, title="VOD Distribution")
>>> plt.savefig("vod_plot.png", dpi=300, bbox_inches='tight')

__init__(grid)

Initialize 2D hemisphere visualizer.

Parameters:

Name Type Description Default
grid HemiGrid

Hemisphere grid to visualize

required

plot_grid_patches(data=None, style=None, ax=None, save_path=None, **style_kwargs)

Plot hemisphere grid as colored patches in polar projection.

Parameters:

Name Type Description Default
data ndarray

Data values per cell. If None, plots uniform grid.

None
style PolarPlotStyle

Styling configuration. If None, uses defaults.

None
ax Axes

Existing polar axes to plot on. If None, creates new figure.

None
save_path Path or str

If provided, saves figure to this path

None
**style_kwargs Any

Override individual style parameters

{}

Returns:

Name Type Description
fig Figure

Figure object

ax Axes

Polar axes with plot

Examples:

>>> fig, ax = viz.plot_grid_patches(
...     data=vod_data,
...     title="VOD Distribution",
...     cmap='plasma',
...     save_path="output.png"
... )

HemisphereVisualizer3D

3D hemisphere visualization using plotly.

Creates interactive 3D plots with rotation, zoom, and hover capabilities. Designed for exploratory data analysis and presentations.

Parameters:

Name Type Description Default
grid HemiGrid

Hemisphere grid to visualize

required

Examples:

>>> from canvod.grids import create_hemigrid
>>> from canvod.viz import HemisphereVisualizer3D
>>>
>>> grid = create_hemigrid(grid_type='equal_area', angular_resolution=10.0)
>>> viz = HemisphereVisualizer3D(grid)
>>> fig = viz.plot_hemisphere_surface(data=vod_data, title="Interactive VOD")
>>> fig.show()

__init__(grid)

Initialize 3D hemisphere visualizer.

Parameters:

Name Type Description Default
grid HemiGrid

Hemisphere grid to visualize

required

plot_hemisphere_surface(data=None, style=None, title=None, colorscale='Viridis', opacity=0.8, show_wireframe=True, show_colorbar=True, width=800, height=600, nan_color=DEFAULT_NAN_COLOR, **kwargs)

Create 3D surface plot on hemisphere with actual cell patches.

Renders grid cells as colored 3D patches (not just points).

Parameters:

Name Type Description Default
data ndarray

Data values per cell. If None, shows grid structure.

None
style PlotStyle

Styling configuration. If None, uses defaults.

None
title str

Plot title

None
colorscale str

Plotly colorscale name

'Viridis'
opacity float

Surface opacity (0=transparent, 1=opaque)

0.8
show_wireframe bool

Show grid lines on surface

True
show_colorbar bool

Display colorbar

True
width int

Figure width in pixels

800
height int

Figure height in pixels

600
nan_color str

Color of cells without data (NaN); not part of the color scale.

'lightgray'
**kwargs Any

Additional plotly trace parameters

{}

Returns:

Type Description
Figure

Interactive 3D figure with cell patches

Examples:

>>> fig = viz.plot_hemisphere_surface(
...     data=vod_data,
...     title="VOD Distribution 3D",
...     colorscale='Plasma',
...     opacity=0.9
... )
>>> fig.write_html("vod_3d.html")

plot_hemisphere_scatter(data=None, title=None, colorscale='Viridis', marker_size=6, opacity=0.8, width=800, height=600)

Create 3D scatter plot of cell centers.

Parameters:

Name Type Description Default
data ndarray

Data values per cell

None
title str

Plot title

None
colorscale str

Plotly colorscale name

'Viridis'
marker_size int or ndarray

Marker size (constant or per-point array)

6
opacity float

Marker opacity

0.8
width int

Figure width

800
height int

Figure height

600

Returns:

Type Description
Figure

Interactive scatter plot

plot_cell_mesh(data=None, title=None, colorscale='Viridis', opacity=0.7, show_edges=True, width=800, height=600, nan_color=DEFAULT_NAN_COLOR)

Create 3D mesh plot showing cell boundaries.

Parameters:

Name Type Description Default
data ndarray

Data values per cell

None
title str

Plot title

None
colorscale str

Plotly colorscale name

'Viridis'
opacity float

Mesh opacity

0.7
show_edges bool

Show cell edges

True
width int

Figure width

800
height int

Figure height

600
nan_color str

Color of cells without data (NaN); not part of the color scale.

'lightgray'

Returns:

Type Description
Figure

Interactive mesh plot

Notes

HTM grids are drawn as one trace per triangle. All other grids are drawn like :meth:plot_hemisphere_surface (one mesh of all cells), with show_edges as its show_wireframe.

add_spherical_overlays(fig, elevation_rings=None, meridians_deg=None, overlay_color='lightgray', line_width=1)

Add elevation rings and meridians to 3D plot.

Parameters:

Name Type Description Default
fig Figure

Existing 3D figure to add overlays to

required
elevation_rings list of int

Elevation angles in degrees above the horizon (0 = horizon, 90 = zenith). Default: [0, 15, 30, 45, 60, 75]

None
meridians_deg list of int

Meridian angles in degrees. Default: [0, 45, 90, 135, 180, 225, 270, 315]

None
overlay_color str

Color for overlay lines

'lightgray'
line_width float

Width of overlay lines

1

Returns:

Name Type Description
fig Figure

Modified figure with overlays

Raises:

Type Description
ValueError

If an elevation is outside [0, 90] degrees.

add_custom_axes(fig, axis_length=1.2, axis_color='black', show_labels=True)

Add custom coordinate axes with labels.

Parameters:

Name Type Description Default
fig Figure

Existing 3D figure

required
axis_length float

Length of axis lines

1.2
axis_color str

Color for axes

'black'
show_labels bool

Show axis labels (E, N, Z)

True

Returns:

Name Type Description
fig Figure

Modified figure with custom axes

PlotStyle dataclass

Unified styling configuration for both 2D and 3D plots.

Parameters:

Name Type Description Default
colormap str

Colormap name (matplotlib or plotly)

'viridis'
colorscale str

Plotly colorscale name

'Viridis'
background_color str

Background color

'white'
text_color str

Text color

'black'
grid_color str

Grid line color

'lightgray'
font_family str

Font family

'sans-serif'
font_size int

Base font size

11
title_size int

Title font size

14
label_size int

Axis label font size

12
edge_linewidth float

Edge line width for cells

0.5
opacity float

3D surface opacity

0.8
marker_size int

3D marker size

8
line_width int

3D line width

1
wireframe_opacity float

3D wireframe transparency

0.2
dark_mode bool

Use dark theme

False

to_polar_style()

Convert to PolarPlotStyle for 2D matplotlib plots.

Returns:

Type Description
PolarPlotStyle

Equivalent 2D styling configuration

to_plotly_layout()

Convert to plotly layout configuration.

Returns:

Type Description
dict

Plotly layout settings

PolarPlotStyle dataclass

Configuration for 2D polar plot styling (matplotlib).

Parameters:

Name Type Description Default
cmap str

Matplotlib colormap name

'viridis'
edgecolor str

Edge color for grid cells

'black'
linewidth float

Line width for cell edges

0.5
alpha float

Transparency (0=transparent, 1=opaque)

1.0
vmin float or None

Minimum value for colormap

None
vmax float or None

Maximum value for colormap

None
title str or None

Plot title

None
figsize tuple of float

Figure size in inches (width, height)

(10, 10)
dpi int

Dots per inch for figure

100
colorbar_label str

Label for colorbar

'Value'
colorbar_shrink float

Colorbar size relative to axis

0.8
colorbar_pad float

Space between axis and colorbar

0.1
colorbar_fontsize int

Font size for colorbar label

11
show_grid bool

Show polar grid lines

True
grid_alpha float

Grid line transparency

0.3
grid_linestyle str

Grid line style

'--'
show_degree_labels bool

Show degree labels on radial axis

True
theta_labels list of int

Elevation angles for labels (degrees)

[0, 30, 60, 90]
projection ('orthographic', 'equidistant')

Radial mapping from zenith angle theta to plot radius rho. 'orthographic' (rho = sin(theta)) is a straight-down view of the 3D hemisphere -- cells compress toward the horizon at the rim. 'equidistant' (rho = theta / (pi/2)) is a true polar plot with elevation rings evenly spaced, the conventional GNSS skyplot convention.

'orthographic'

visualize_grid(grid, data=None, style=None, **kwargs)

Visualize hemispherical grid in 2D polar projection.

Convenience function providing simple interface to 2D visualization.

Parameters:

Name Type Description Default
grid HemiGrid

Grid to visualize

required
data ndarray

Data values per cell. If None, plots uniform grid.

None
style PolarPlotStyle

Styling configuration. If None, uses defaults.

None
**kwargs Any

Additional style parameter overrides

{}

Returns:

Name Type Description
fig Figure

Figure object

ax Axes

Polar axes object

Examples:

>>> from canvod.grids import create_hemigrid
>>> from canvod.viz import visualize_grid
>>>
>>> grid = create_hemigrid(grid_type='equal_area', angular_resolution=10.0)
>>> fig, ax = visualize_grid(grid, data=vod_data, cmap='viridis')
>>> plt.savefig("vod_plot.png", dpi=300)

visualize_grid_3d(grid, data=None, title=None, colorscale='Viridis', add_overlays=False, add_axes=False, **kwargs)

Visualize hemispherical grid in 3D interactive plot.

Convenience function providing simple interface to 3D visualization.

Parameters:

Name Type Description Default
grid HemiGrid

Grid to visualize

required
data ndarray

Data values per cell

None
title str

Plot title

None
colorscale str

Plotly colorscale name

'Viridis'
add_overlays bool

Add elevation rings and meridians

False
add_axes bool

Add custom coordinate axes

False
**kwargs Any

Additional parameters passed to plot_hemisphere_surface

{}

Returns:

Name Type Description
fig Figure

Interactive 3D figure

Examples:

>>> from canvod.grids import create_hemigrid
>>> from canvod.viz import visualize_grid_3d
>>>
>>> grid = create_hemigrid(grid_type='equal_area', angular_resolution=10.0)
>>> fig = visualize_grid_3d(
...     grid,
...     data=vod_data,
...     title="VOD 3D",
...     add_overlays=True
... )
>>> fig.show()

add_tissot_indicatrix(ax, grid, radius_deg=None, n_sample=None, facecolor='gold', alpha=0.6, edgecolor='black', linewidth=0.5, projection='orthographic')

Add Tissot's indicatrix circles to existing polar plot.

Adds equal-sized circles to visualize grid distortion. In equal-area grids, circles should appear roughly equal-sized. Variation indicates distortion.

Parameters:

Name Type Description Default
ax Axes

Existing polar axis to add circles to

required
grid HemiGrid

Grid instance

required
radius_deg float

Angular radius of circles in degrees. If None, auto-calculated as angular_resolution / 8.

None
n_sample int

Subsample cells (use every nth cell) for performance. If None, shows all cells.

None
facecolor str

Fill color for circles

'gold'
alpha float

Transparency (0=transparent, 1=opaque)

0.6
edgecolor str

Edge color for circles

'black'
linewidth float

Edge line width

0.5
projection ('orthographic', 'equidistant')

Must match the projection used for the underlying ax (see PolarPlotStyle.projection), otherwise circles will be misaligned with the grid patches.

'orthographic'

Returns:

Name Type Description
ax Axes

Modified axis with Tissot circles added

Examples:

>>> fig, ax = visualize_grid(grid, data=vod_data)
>>> add_tissot_indicatrix(ax, grid, radius_deg=3, n_sample=5)
>>> plt.savefig("vod_with_tissot.png")

create_publication_style()

Create styling optimized for publication-quality figures.

Returns:

Type Description
PlotStyle

Publication-optimized styling configuration

Examples:

>>> style = create_publication_style()
>>> viz.plot_2d(data=vod_data, style=style)

create_interactive_style(dark_mode=True)

Create styling optimized for interactive exploration.

Parameters:

Name Type Description Default
dark_mode bool

Use dark theme for better screen viewing

True

Returns:

Type Description
PlotStyle

Interactive-optimized styling configuration

Examples:

>>> style = create_interactive_style(dark_mode=True)
>>> viz.plot_3d(data=vod_data, style=style)

Unified visualizer

Unified hemisphere visualization API combining 2D and 3D capabilities.

Provides a single interface for both matplotlib (publication) and plotly (interactive) plots.

HemisphereVisualizer

Unified hemisphere visualizer combining 2D and 3D capabilities.

Provides consistent API for both publication-quality matplotlib plots and interactive plotly visualizations. Handles styling coordination between different rendering backends.

Parameters:

Name Type Description Default
grid HemiGrid

Hemisphere grid to visualize

required

Examples:

Create both 2D and 3D visualizations::

from canvod.grids import create_hemigrid
from canvod.viz import HemisphereVisualizer

grid = create_hemigrid(grid_type='equal_area', angular_resolution=10.0)
viz = HemisphereVisualizer(grid)

# Publication-quality 2D plot
fig_2d, ax_2d = viz.plot_2d(
    data=vod_data,
    title="VOD Distribution",
    save_path="publication.png"
)

# Interactive 3D plot
fig_3d = viz.plot_3d(
    data=vod_data,
    title="Interactive VOD Explorer"
)
fig_3d.show()

Switch styles easily::

# Publication style
pub_style = create_publication_style()
viz.set_style(pub_style)
fig, ax = viz.plot_2d(data=vod_data)

# Interactive style
int_style = create_interactive_style(dark_mode=True)
viz.set_style(int_style)
fig = viz.plot_3d(data=vod_data)

__init__(grid)

Initialize unified visualizer.

Parameters:

Name Type Description Default
grid HemiGrid

Hemisphere grid to visualize

required

set_style(style)

Set unified styling for both 2D and 3D plots.

Parameters:

Name Type Description Default
style PlotStyle

Styling configuration

required

Examples:

>>> pub_style = create_publication_style()
>>> viz.set_style(pub_style)
>>> fig, ax = viz.plot_2d(data=vod_data)

plot_2d(data=None, title=None, ax=None, save_path=None, style=None, **kwargs)

Create 2D publication-quality plot.

Parameters:

Name Type Description Default
data ndarray

Data values per cell

None
title str

Plot title

None
ax Axes

Existing axes to plot on

None
save_path Path or str

Save figure to this path

None
style PolarPlotStyle

Override default 2D style

None
**kwargs Any

Additional styling parameters

{}

Returns:

Name Type Description
fig Figure

Figure object

ax Axes

Polar axes with plot

Examples:

>>> fig, ax = viz.plot_2d(
...     data=vod_data,
...     title="VOD Distribution",
...     cmap='plasma',
...     save_path="output.png",
...     dpi=300
... )

plot_3d(data=None, title=None, style=None, **kwargs)

Create 3D interactive plot.

Parameters:

Name Type Description Default
data ndarray

Data values per cell

None
title str

Plot title

None
style PlotStyle

Override default 3D style

None
**kwargs Any

Additional plotly parameters

{}

Returns:

Type Description
Figure

Interactive 3D figure

Examples:

>>> fig = viz.plot_3d(
...     data=vod_data,
...     title="Interactive VOD",
...     opacity=0.9,
...     width=1000,
...     height=800
... )
>>> fig.show()
>>> fig.write_html("interactive.html")

plot_3d_mesh(data=None, title=None, **kwargs)

Create 3D mesh plot showing cell boundaries.

Parameters:

Name Type Description Default
data ndarray

Data values per cell

None
title str

Plot title

None
**kwargs Any

Additional plotly parameters

{}

Returns:

Type Description
Figure

Interactive mesh figure

Examples:

>>> fig = viz.plot_3d_mesh(
...     data=vod_data,
...     title="VOD Mesh View",
...     opacity=0.7
... )

create_comparison_plot(data=None, title_2d='2D Polar View', title_3d='3D Hemisphere View', save_2d=None, save_3d=None)

Create both 2D and 3D plots for comparison.

Parameters:

Name Type Description Default
data ndarray

Data values per cell

None
title_2d str

Title for 2D plot

"2D Polar View"
title_3d str

Title for 3D plot

"3D Hemisphere View"
save_2d Path or str

Save 2D figure to this path

None
save_3d Path or str

Save 3D figure to this path (HTML)

None

Returns:

Name Type Description
plot_2d tuple of Figure and Axes

2D matplotlib plot

plot_3d Figure

3D plotly plot

Examples:

>>> (fig_2d, ax_2d), fig_3d = viz.create_comparison_plot(
...     data=vod_data,
...     save_2d="comparison_2d.png",
...     save_3d="comparison_3d.html"
... )
>>> plt.show()  # Show 2D
>>> fig_3d.show()  # Show 3D

create_publication_figure(data=None, title='Hemispherical Data Distribution', save_path=None, dpi=300, **kwargs)

Create publication-ready figure with optimal styling.

Parameters:

Name Type Description Default
data ndarray

Data values per cell

None
title str

Plot title

"Hemispherical Data Distribution"
save_path Path or str

Save figure to this path

None
dpi int

Resolution in dots per inch

300
**kwargs Any

Additional styling parameters

{}

Returns:

Name Type Description
fig Figure

Publication-ready figure

ax Axes

Styled polar axes

Examples:

>>> fig, ax = viz.create_publication_figure(
...     data=vod_data,
...     title="VOD Distribution Over ExampleSite Site",
...     save_path="paper_figure_3.png",
...     dpi=600
... )

create_interactive_explorer(data=None, title='Interactive Data Explorer', dark_mode=True, save_html=None)

Create interactive explorer with optimal settings.

Parameters:

Name Type Description Default
data ndarray

Data values per cell

None
title str

Plot title

"Interactive Data Explorer"
dark_mode bool

Use dark theme

True
save_html Path or str

Save HTML to this path

None

Returns:

Type Description
Figure

Interactive explorer figure

Examples:

>>> fig = viz.create_interactive_explorer(
...     data=vod_data,
...     title="VOD Explorer",
...     dark_mode=True,
...     save_html="explorer.html"
... )
>>> fig.show()

2D plots

2D hemisphere visualization using matplotlib for publication-quality plots.

Provides polar projection plotting of hemispherical grids with various rendering methods.

HemisphereVisualizer2D

2D hemisphere visualization using matplotlib.

Creates publication-quality polar projection plots of hemispherical grids. Supports multiple grid types and rendering methods.

Parameters:

Name Type Description Default
grid HemiGrid

Hemisphere grid to visualize

required

Examples:

>>> from canvod.grids import create_hemigrid
>>> from canvod.viz import HemisphereVisualizer2D
>>>
>>> grid = create_hemigrid(grid_type='equal_area', angular_resolution=10.0)
>>> viz = HemisphereVisualizer2D(grid)
>>> fig, ax = viz.plot_grid_patches(data=vod_data, title="VOD Distribution")
>>> plt.savefig("vod_plot.png", dpi=300, bbox_inches='tight')

__init__(grid)

Initialize 2D hemisphere visualizer.

Parameters:

Name Type Description Default
grid HemiGrid

Hemisphere grid to visualize

required

plot_grid_patches(data=None, style=None, ax=None, save_path=None, **style_kwargs)

Plot hemisphere grid as colored patches in polar projection.

Parameters:

Name Type Description Default
data ndarray

Data values per cell. If None, plots uniform grid.

None
style PolarPlotStyle

Styling configuration. If None, uses defaults.

None
ax Axes

Existing polar axes to plot on. If None, creates new figure.

None
save_path Path or str

If provided, saves figure to this path

None
**style_kwargs Any

Override individual style parameters

{}

Returns:

Name Type Description
fig Figure

Figure object

ax Axes

Polar axes with plot

Examples:

>>> fig, ax = viz.plot_grid_patches(
...     data=vod_data,
...     title="VOD Distribution",
...     cmap='plasma',
...     save_path="output.png"
... )

visualize_grid(grid, data=None, style=None, **kwargs)

Visualize hemispherical grid in 2D polar projection.

Convenience function providing simple interface to 2D visualization.

Parameters:

Name Type Description Default
grid HemiGrid

Grid to visualize

required
data ndarray

Data values per cell. If None, plots uniform grid.

None
style PolarPlotStyle

Styling configuration. If None, uses defaults.

None
**kwargs Any

Additional style parameter overrides

{}

Returns:

Name Type Description
fig Figure

Figure object

ax Axes

Polar axes object

Examples:

>>> from canvod.grids import create_hemigrid
>>> from canvod.viz import visualize_grid
>>>
>>> grid = create_hemigrid(grid_type='equal_area', angular_resolution=10.0)
>>> fig, ax = visualize_grid(grid, data=vod_data, cmap='viridis')
>>> plt.savefig("vod_plot.png", dpi=300)

add_tissot_indicatrix(ax, grid, radius_deg=None, n_sample=None, facecolor='gold', alpha=0.6, edgecolor='black', linewidth=0.5, projection='orthographic')

Add Tissot's indicatrix circles to existing polar plot.

Adds equal-sized circles to visualize grid distortion. In equal-area grids, circles should appear roughly equal-sized. Variation indicates distortion.

Parameters:

Name Type Description Default
ax Axes

Existing polar axis to add circles to

required
grid HemiGrid

Grid instance

required
radius_deg float

Angular radius of circles in degrees. If None, auto-calculated as angular_resolution / 8.

None
n_sample int

Subsample cells (use every nth cell) for performance. If None, shows all cells.

None
facecolor str

Fill color for circles

'gold'
alpha float

Transparency (0=transparent, 1=opaque)

0.6
edgecolor str

Edge color for circles

'black'
linewidth float

Edge line width

0.5
projection ('orthographic', 'equidistant')

Must match the projection used for the underlying ax (see PolarPlotStyle.projection), otherwise circles will be misaligned with the grid patches.

'orthographic'

Returns:

Name Type Description
ax Axes

Modified axis with Tissot circles added

Examples:

>>> fig, ax = visualize_grid(grid, data=vod_data)
>>> add_tissot_indicatrix(ax, grid, radius_deg=3, n_sample=5)
>>> plt.savefig("vod_with_tissot.png")

3D plots

3D hemisphere visualization using plotly for interactive exploration.

Provides interactive 3D sphere surface plots with zoom, pan, and rotation capabilities.

HemisphereVisualizer3D

3D hemisphere visualization using plotly.

Creates interactive 3D plots with rotation, zoom, and hover capabilities. Designed for exploratory data analysis and presentations.

Parameters:

Name Type Description Default
grid HemiGrid

Hemisphere grid to visualize

required

Examples:

>>> from canvod.grids import create_hemigrid
>>> from canvod.viz import HemisphereVisualizer3D
>>>
>>> grid = create_hemigrid(grid_type='equal_area', angular_resolution=10.0)
>>> viz = HemisphereVisualizer3D(grid)
>>> fig = viz.plot_hemisphere_surface(data=vod_data, title="Interactive VOD")
>>> fig.show()

__init__(grid)

Initialize 3D hemisphere visualizer.

Parameters:

Name Type Description Default
grid HemiGrid

Hemisphere grid to visualize

required

plot_hemisphere_surface(data=None, style=None, title=None, colorscale='Viridis', opacity=0.8, show_wireframe=True, show_colorbar=True, width=800, height=600, nan_color=DEFAULT_NAN_COLOR, **kwargs)

Create 3D surface plot on hemisphere with actual cell patches.

Renders grid cells as colored 3D patches (not just points).

Parameters:

Name Type Description Default
data ndarray

Data values per cell. If None, shows grid structure.

None
style PlotStyle

Styling configuration. If None, uses defaults.

None
title str

Plot title

None
colorscale str

Plotly colorscale name

'Viridis'
opacity float

Surface opacity (0=transparent, 1=opaque)

0.8
show_wireframe bool

Show grid lines on surface

True
show_colorbar bool

Display colorbar

True
width int

Figure width in pixels

800
height int

Figure height in pixels

600
nan_color str

Color of cells without data (NaN); not part of the color scale.

'lightgray'
**kwargs Any

Additional plotly trace parameters

{}

Returns:

Type Description
Figure

Interactive 3D figure with cell patches

Examples:

>>> fig = viz.plot_hemisphere_surface(
...     data=vod_data,
...     title="VOD Distribution 3D",
...     colorscale='Plasma',
...     opacity=0.9
... )
>>> fig.write_html("vod_3d.html")

plot_hemisphere_scatter(data=None, title=None, colorscale='Viridis', marker_size=6, opacity=0.8, width=800, height=600)

Create 3D scatter plot of cell centers.

Parameters:

Name Type Description Default
data ndarray

Data values per cell

None
title str

Plot title

None
colorscale str

Plotly colorscale name

'Viridis'
marker_size int or ndarray

Marker size (constant or per-point array)

6
opacity float

Marker opacity

0.8
width int

Figure width

800
height int

Figure height

600

Returns:

Type Description
Figure

Interactive scatter plot

plot_cell_mesh(data=None, title=None, colorscale='Viridis', opacity=0.7, show_edges=True, width=800, height=600, nan_color=DEFAULT_NAN_COLOR)

Create 3D mesh plot showing cell boundaries.

Parameters:

Name Type Description Default
data ndarray

Data values per cell

None
title str

Plot title

None
colorscale str

Plotly colorscale name

'Viridis'
opacity float

Mesh opacity

0.7
show_edges bool

Show cell edges

True
width int

Figure width

800
height int

Figure height

600
nan_color str

Color of cells without data (NaN); not part of the color scale.

'lightgray'

Returns:

Type Description
Figure

Interactive mesh plot

Notes

HTM grids are drawn as one trace per triangle. All other grids are drawn like :meth:plot_hemisphere_surface (one mesh of all cells), with show_edges as its show_wireframe.

add_spherical_overlays(fig, elevation_rings=None, meridians_deg=None, overlay_color='lightgray', line_width=1)

Add elevation rings and meridians to 3D plot.

Parameters:

Name Type Description Default
fig Figure

Existing 3D figure to add overlays to

required
elevation_rings list of int

Elevation angles in degrees above the horizon (0 = horizon, 90 = zenith). Default: [0, 15, 30, 45, 60, 75]

None
meridians_deg list of int

Meridian angles in degrees. Default: [0, 45, 90, 135, 180, 225, 270, 315]

None
overlay_color str

Color for overlay lines

'lightgray'
line_width float

Width of overlay lines

1

Returns:

Name Type Description
fig Figure

Modified figure with overlays

Raises:

Type Description
ValueError

If an elevation is outside [0, 90] degrees.

add_custom_axes(fig, axis_length=1.2, axis_color='black', show_labels=True)

Add custom coordinate axes with labels.

Parameters:

Name Type Description Default
fig Figure

Existing 3D figure

required
axis_length float

Length of axis lines

1.2
axis_color str

Color for axes

'black'
show_labels bool

Show axis labels (E, N, Z)

True

Returns:

Name Type Description
fig Figure

Modified figure with custom axes

visualize_grid_3d(grid, data=None, title=None, colorscale='Viridis', add_overlays=False, add_axes=False, **kwargs)

Visualize hemispherical grid in 3D interactive plot.

Convenience function providing simple interface to 3D visualization.

Parameters:

Name Type Description Default
grid HemiGrid

Grid to visualize

required
data ndarray

Data values per cell

None
title str

Plot title

None
colorscale str

Plotly colorscale name

'Viridis'
add_overlays bool

Add elevation rings and meridians

False
add_axes bool

Add custom coordinate axes

False
**kwargs Any

Additional parameters passed to plot_hemisphere_surface

{}

Returns:

Name Type Description
fig Figure

Interactive 3D figure

Examples:

>>> from canvod.grids import create_hemigrid
>>> from canvod.viz import visualize_grid_3d
>>>
>>> grid = create_hemigrid(grid_type='equal_area', angular_resolution=10.0)
>>> fig = visualize_grid_3d(
...     grid,
...     data=vod_data,
...     title="VOD 3D",
...     add_overlays=True
... )
>>> fig.show()

Styles

Styling configuration for visualizations.

Provides consistent styling across 2D matplotlib and 3D plotly visualizations, including publication-quality RSE journal style and colorscale utilities.

PolarPlotStyle dataclass

Configuration for 2D polar plot styling (matplotlib).

Parameters:

Name Type Description Default
cmap str

Matplotlib colormap name

'viridis'
edgecolor str

Edge color for grid cells

'black'
linewidth float

Line width for cell edges

0.5
alpha float

Transparency (0=transparent, 1=opaque)

1.0
vmin float or None

Minimum value for colormap

None
vmax float or None

Maximum value for colormap

None
title str or None

Plot title

None
figsize tuple of float

Figure size in inches (width, height)

(10, 10)
dpi int

Dots per inch for figure

100
colorbar_label str

Label for colorbar

'Value'
colorbar_shrink float

Colorbar size relative to axis

0.8
colorbar_pad float

Space between axis and colorbar

0.1
colorbar_fontsize int

Font size for colorbar label

11
show_grid bool

Show polar grid lines

True
grid_alpha float

Grid line transparency

0.3
grid_linestyle str

Grid line style

'--'
show_degree_labels bool

Show degree labels on radial axis

True
theta_labels list of int

Elevation angles for labels (degrees)

[0, 30, 60, 90]
projection ('orthographic', 'equidistant')

Radial mapping from zenith angle theta to plot radius rho. 'orthographic' (rho = sin(theta)) is a straight-down view of the 3D hemisphere -- cells compress toward the horizon at the rim. 'equidistant' (rho = theta / (pi/2)) is a true polar plot with elevation rings evenly spaced, the conventional GNSS skyplot convention.

'orthographic'

PlotStyle dataclass

Unified styling configuration for both 2D and 3D plots.

Parameters:

Name Type Description Default
colormap str

Colormap name (matplotlib or plotly)

'viridis'
colorscale str

Plotly colorscale name

'Viridis'
background_color str

Background color

'white'
text_color str

Text color

'black'
grid_color str

Grid line color

'lightgray'
font_family str

Font family

'sans-serif'
font_size int

Base font size

11
title_size int

Title font size

14
label_size int

Axis label font size

12
edge_linewidth float

Edge line width for cells

0.5
opacity float

3D surface opacity

0.8
marker_size int

3D marker size

8
line_width int

3D line width

1
wireframe_opacity float

3D wireframe transparency

0.2
dark_mode bool

Use dark theme

False

to_polar_style()

Convert to PolarPlotStyle for 2D matplotlib plots.

Returns:

Type Description
PolarPlotStyle

Equivalent 2D styling configuration

to_plotly_layout()

Convert to plotly layout configuration.

Returns:

Type Description
dict

Plotly layout settings

Colorscale dataclass

Unified colorscale that converts between Plotly and matplotlib.

Parameters:

Name Type Description Default
name str

Colorscale identifier.

required
stops list of (float, str)

Normalized [(position, color), ...] where position is 0–1.

list()

from_matplotlib(cmap_name, n_colors=256) classmethod

Create from a matplotlib colormap name.

from_colors(colors, name='custom') classmethod

Create from a list of color strings (hex, named, or rgb()).

to_matplotlib(n_colors=256)

Convert to a matplotlib LinearSegmentedColormap.

Returns:

Type Description
Colormap

to_plotly()

Return Plotly-compatible colorscale list.

create_publication_style()

Create styling optimized for publication-quality figures.

Returns:

Type Description
PlotStyle

Publication-optimized styling configuration

Examples:

>>> style = create_publication_style()
>>> viz.plot_2d(data=vod_data, style=style)

create_rse_style()

Create styling matching Remote Sensing of Environment journal guidelines.

Returns:

Type Description
PlotStyle

RSE-compatible styling with Arial/Helvetica fonts, 300 DPI, inward ticks, and colorblind-friendly color cycle.

create_interactive_style(dark_mode=True)

Create styling optimized for interactive exploration.

Parameters:

Name Type Description Default
dark_mode bool

Use dark theme for better screen viewing

True

Returns:

Type Description
PlotStyle

Interactive-optimized styling configuration

Examples:

>>> style = create_interactive_style(dark_mode=True)
>>> viz.plot_3d(data=vod_data, style=style)

apply_rse_style()

Apply RSE journal style globally via plt.rcParams.

Returns:

Type Description
dict

The applied rcParams dictionary.

rse_context()

Return a context manager that temporarily applies RSE style.

Usage::

with rse_context():
    fig, ax = plt.subplots()
    ...

rse_style(func)

Decorator that applies RSE style to a plotting function.

The decorated function is expected to return (fig, axes).

style_colorbar(cbar, label=None)

Apply RSE-compatible styling to a matplotlib colorbar.

Parameters:

Name Type Description Default
cbar Colorbar

Colorbar instance to style.

required
label str

Label text.

None

Returns:

Type Description
Colorbar

The styled colorbar.

fix_figure_for_dark_mode(fig, axes=None)

Set explicit white backgrounds so figures render correctly in dark IDEs.

Parameters:

Name Type Description Default
fig Figure

Figure to fix.

required
axes list

Specific axes; defaults to all axes in the figure.

None

Returns:

Type Description
Figure