Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
0ed5db8
feat: Add customization APIs
AlejandroFernandezLuces Feb 6, 2026
d85217f
fix: unneeded docs
AlejandroFernandezLuces Feb 6, 2026
082546e
chore: adding changelog file 465.miscellaneous.md [dependabot-skip]
pyansys-ci-bot Feb 6, 2026
43ab206
fix: bugs and docs
AlejandroFernandezLuces Feb 6, 2026
7aed2b6
Merge branch 'feat/customization-api' of https://github.com/ansys/ans…
AlejandroFernandezLuces Feb 6, 2026
9626ba9
feat: add more customization apis
moe-ad Feb 8, 2026
4205584
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Feb 8, 2026
7480408
Merge branch 'main' into feat/customization-api
AlejandroFernandezLuces Feb 9, 2026
c4a1118
Merge branch 'main' into feat/customization-api
moe-ad Feb 9, 2026
6c24cd5
Merge branch 'main' into feat/customization-api
AlejandroFernandezLuces Feb 10, 2026
2b1c73a
Merge branch 'feat/customization-api' of https://github.com/ansys/ans…
AlejandroFernandezLuces Feb 10, 2026
44a33a8
fix: Revert API changes
AlejandroFernandezLuces Feb 10, 2026
9185175
test: Add tests for the public API
AlejandroFernandezLuces Feb 10, 2026
98e857e
Merge branch 'main' into feat/customization-api
AlejandroFernandezLuces Feb 11, 2026
26d450e
fix: Avoid using 3DText
AlejandroFernandezLuces Feb 11, 2026
e10f37a
Merge branch 'feat/customization-api' of https://github.com/ansys/ans…
AlejandroFernandezLuces Feb 11, 2026
1ab9bb7
fix: Fixes and reset image cache
AlejandroFernandezLuces Feb 11, 2026
e8f977a
chore: adding changelog file 465.maintenance.md [dependabot-skip]
pyansys-ci-bot Feb 11, 2026
586308a
fix: add text
AlejandroFernandezLuces Feb 11, 2026
995e084
Merge branch 'feat/customization-api' of https://github.com/ansys/ans…
AlejandroFernandezLuces Feb 11, 2026
45e9362
fix: Revert
AlejandroFernandezLuces Feb 11, 2026
1358546
Merge branch 'main' into feat/customization-api
AlejandroFernandezLuces Feb 11, 2026
9673fe3
debug
AlejandroFernandezLuces Feb 11, 2026
f7c3b0a
debug
AlejandroFernandezLuces Feb 11, 2026
9a4d2d4
debug
AlejandroFernandezLuces Feb 11, 2026
a926f70
debug
AlejandroFernandezLuces Feb 11, 2026
4decc89
debug: Remove doc dep, comment example except show
AlejandroFernandezLuces Feb 12, 2026
2279c8d
debug: remove example
AlejandroFernandezLuces Feb 12, 2026
d2393f2
fix: Example
AlejandroFernandezLuces Feb 12, 2026
1a5464f
fix: Improve example
AlejandroFernandezLuces Feb 12, 2026
0c7b7fc
fix: Example
AlejandroFernandezLuces Feb 12, 2026
5b6e175
Update ci_cd.yml
AlejandroFernandezLuces Feb 12, 2026
1f861e5
fix: Example titles
AlejandroFernandezLuces Feb 12, 2026
d23397b
Merge branch 'feat/customization-api' of https://github.com/ansys/ans…
AlejandroFernandezLuces Feb 12, 2026
83983a3
Merge branch 'main' into feat/customization-api
AlejandroFernandezLuces Feb 13, 2026
8837bf8
fix: Add sections
AlejandroFernandezLuces Feb 13, 2026
a8ef11a
chore: adding changelog file 465.added.md [dependabot-skip]
pyansys-ci-bot Feb 13, 2026
a966121
fix: Typehints
AlejandroFernandezLuces Feb 13, 2026
3c5051b
Merge branch 'feat/customization-api' of https://github.com/ansys/ans…
AlejandroFernandezLuces Feb 13, 2026
260264f
fix: Homogenize examples
AlejandroFernandezLuces Feb 13, 2026
b938010
fix: Remove unneeded check
AlejandroFernandezLuces Feb 13, 2026
72f801f
fix: Feedback
AlejandroFernandezLuces Feb 13, 2026
f840d88
chore: adding changelog file 465.maintenance.md [dependabot-skip]
pyansys-ci-bot Feb 13, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci_cd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ on:

env:
MAIN_PYTHON_VERSION: '3.13'
RESET_IMAGE_CACHE: 1
RESET_IMAGE_CACHE: 2
PACKAGE_NAME: ansys-tools-visualization-interface
DOCUMENTATION_CNAME: visualization-interface.tools.docs.pyansys.com
IN_GITHUB_ACTIONS: true
Expand Down
1 change: 1 addition & 0 deletions doc/changelog.d/465.maintenance.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Feat: Add customization APIs
2 changes: 1 addition & 1 deletion examples/00-basic-pyvista-examples/README.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Basic usage examples
====================

These examples show how to use the general plotter included in the Visualization Interface Tool.
These examples show how to use the general plotter included in the Visualization Interface Tool.
8 changes: 4 additions & 4 deletions examples/00-basic-pyvista-examples/animation.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,9 @@

from ansys.tools.visualization_interface import Plotter

###############################################################################
##############################
# Create sample animation data
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Generate a series of meshes representing a wave propagation over time.

def create_wave_mesh(time_step, n_points=50):
Expand All @@ -62,7 +62,7 @@ def create_wave_mesh(time_step, n_points=50):
# Create 30 frames
frames = [create_wave_mesh(i) for i in range(30)]

###############################################################################
##############################################
# Display animation with interactive controls
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Create and show an animation with play/pause, stop, and frame navigation.
Expand All @@ -78,7 +78,7 @@ def create_wave_mesh(time_step, n_points=50):
# Display with interactive controls
animation.show()

###############################################################################
######################
# Interactive Controls
# ~~~~~~~~~~~~~~~~~~~~
# The animation window includes the following controls:
Expand Down
94 changes: 94 additions & 0 deletions examples/00-basic-pyvista-examples/customization_api.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
# Copyright (C) 2024 - 2026 ANSYS, Inc. and/or its affiliates.
# SPDX-License-Identifier: MIT
#
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

"""
.. _api_ex:

Customization API example
=========================

This example demonstrates how to use the customization API of the visualization interface
to add various elements to a PyVista scene, such as points, lines, planes, and text annotations.
The example also shows how to plot a simple sphere mesh and customize its appearance.

"""


from ansys.tools.visualization_interface import Plotter
import pyvista as pv

# Create a plotter using the Plotly backend and add basic geometry.

plotter = Plotter()

# Add a sphere - this works fine
sphere = pv.Sphere(radius=1.0, center=(0, 0, 0))
plotter.plot(sphere)


# Add point markers to highlight specific locations.

key_points = [
[1, 0, 0], # Point on X axis
[0, 1, 0], # Point on Y axis
[0, 0, 1], # Point on Z axis
]

plotter.add_points(key_points, color='red', size=10)

# Add line segments to show coordinate axes.

# X axis
x_axis = [[0, 0, 0], [1.5, 0, 0]]
plotter.add_lines(x_axis, color='red', width=4.0)

# Y axis
y_axis = [[0, 0, 0], [0, 1.5, 0]]
plotter.add_lines(y_axis, color='green', width=4.0)

# Z axis
z_axis = [[0, 0, 0], [0, 0, 1.5]]
plotter.add_lines(z_axis, color='blue', width=4.0)


# Add a plane to show a reference surface.

plotter.add_planes(
center=(0, 0, 0),
normal=(0, 0, 1),
i_size=2.5,
j_size=2.5,
color='lightblue',
opacity=0.2
)


# Scene title at the top center
plotter.add_text("Customization API Example", position=(0.5, 0.95), font_size=18, color='white')

# Additional labels at the top corners
plotter.add_text("Plotly Backend", position=(0.05, 0.95), font_size=12, color='lightblue')
plotter.add_text("3D Visualization", position=(0.95, 0.95), font_size=12, color='lightgreen')

# Display the visualization with all customizations.

plotter.show()
100 changes: 100 additions & 0 deletions examples/01-basic-plotly-examples/customization_api.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
# Copyright (C) 2024 - 2026 ANSYS, Inc. and/or its affiliates.
# SPDX-License-Identifier: MIT
#
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

"""
.. _plotly_customization_api_example:

Backend-Agnostic Customization APIs (Plotly)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

This example demonstrates the backend-agnostic customization APIs with
the Plotly backend.

The same API calls work with both PyVista and Plotly backends, demonstrating
the true backend-agnostic nature of these methods.
"""

import pyvista as pv
from ansys.tools.visualization_interface import Plotter
from ansys.tools.visualization_interface.backends.plotly.plotly_interface import PlotlyBackend

# Create a plotter using the Plotly backend and add basic geometry.

plotter = Plotter(backend=PlotlyBackend())

# Add a sphere - this works fine
sphere = pv.Sphere(radius=1.0, center=(0, 0, 0))
plotter.plot(sphere)

# Add point markers to highlight specific locations.

key_points = [
[1, 0, 0], # Point on X axis
[0, 1, 0], # Point on Y axis
[0, 0, 1], # Point on Z axis
]

plotter.add_points(key_points, color='red', size=10)

# Add line segments to show coordinate axes.

# X axis
x_axis = [[0, 0, 0], [1.5, 0, 0]]
plotter.add_lines(x_axis, color='red', width=4.0)

# Y axis
y_axis = [[0, 0, 0], [0, 1.5, 0]]
plotter.add_lines(y_axis, color='green', width=4.0)

# Z axis
z_axis = [[0, 0, 0], [0, 0, 1.5]]
plotter.add_lines(z_axis, color='blue', width=4.0)



# Add a plane to show a reference surface.

plotter.add_planes(
center=(0, 0, 0),
normal=(0, 0, 1),
i_size=2.5,
j_size=2.5,
color='lightblue',
opacity=0.2
)


# Add text annotations using 2D normalized coordinates (0-1 range).

# Scene title at the top center
plotter.add_text("Customization API Example", position=(0.5, 0.95), font_size=18, color='white')

# Additional labels at the top corners
plotter.add_text("Plotly Backend", position=(0.05, 0.95), font_size=12, color='lightblue')
plotter.add_text("3D Visualization", position=(0.95, 0.95), font_size=12, color='lightgreen')


# Display the visualization with all customizations.


# Uncomment to show in browser:
plotter.show()
130 changes: 129 additions & 1 deletion src/ansys/tools/visualization_interface/backends/_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@

"""Module for the backend base class."""
from abc import ABC, abstractmethod
from typing import Any, Iterable
from typing import Any, Iterable, List, Optional, Tuple, Union


class BaseBackend(ABC):
Expand All @@ -42,3 +42,131 @@ def plot_iter(self, plotting_list: Iterable):
def show(self):
"""Show the plotted objects."""
raise NotImplementedError("show method must be implemented")

@abstractmethod
def add_points(
self,
points: Union[List, Any],
color: str = "red",
size: float = 10.0,
**kwargs
) -> Any:
"""Add point markers to the scene.

Parameters
----------
points : Union[List, Any]
Points to add. Can be a list of coordinates or array-like object.
Expected format: [[x1, y1, z1], [x2, y2, z2], ...] or Nx3 array.
color : str, default: "red"
Color of the points.
size : float, default: 10.0
Size of the point markers.
**kwargs : dict
Additional backend-specific keyword arguments.

Returns
-------
Any
Backend-specific actor or object representing the added points.
"""
raise NotImplementedError("add_points method must be implemented")

@abstractmethod
def add_lines(
self,
points: Union[List, Any],
connections: Optional[Union[List, Any]] = None,
color: str = "white",
width: float = 1.0,
**kwargs
) -> Any:
"""Add line segments to the scene.

Parameters
----------
points : Union[List, Any]
Points defining the lines. Can be a list of coordinates or array-like object.
Expected format: [[x1, y1, z1], [x2, y2, z2], ...] or Nx3 array.
connections : Optional[Union[List, Any]], default: None
Line connectivity. If None, connects points sequentially.
Expected format: [[start_idx1, end_idx1], [start_idx2, end_idx2], ...]
or Mx2 array where M is the number of lines.
color : str, default: "white"
Color of the lines.
width : float, default: 1.0
Width of the lines.
**kwargs : dict
Additional backend-specific keyword arguments.

Returns
-------
Any
Backend-specific actor or object representing the added lines.
"""
raise NotImplementedError("add_lines method must be implemented")

@abstractmethod
def add_planes(
self,
center: Tuple[float, float, float] = (0.0, 0.0, 0.0),
normal: Tuple[float, float, float] = (0.0, 0.0, 1.0),
i_size: float = 1.0,
j_size: float = 1.0,
**kwargs
) -> Any:
"""Add a plane to the scene.

Parameters
----------
center : Tuple[float, float, float], default: (0.0, 0.0, 0.0)
Center point of the plane (x, y, z).
normal : Tuple[float, float, float], default: (0.0, 0.0, 1.0)
Normal vector of the plane (x, y, z).
i_size : float, default: 1.0
Size of the plane in the i direction.
j_size : float, default: 1.0
Size of the plane in the j direction.
**kwargs : dict
Additional backend-specific keyword arguments.

Returns
-------
Any
Backend-specific actor or object representing the added plane.
"""
raise NotImplementedError("add_planes method must be implemented")

@abstractmethod
def add_text(
self,
text: str,
position: Union[Tuple[float, float], Tuple[float, float, float], str],
font_size: int = 12,
color: str = "white",
**kwargs
) -> Any:
"""Add text to the scene.

Parameters
----------
text : str
Text string to display.
position : Union[Tuple[float, float], Tuple[float, float, float], str]
Position for the text. Can be 2D (x, y) for screen coordinates,
3D (x, y, z) for world coordinates, or a string position like
'upper_left', 'upper_right', 'lower_left', 'lower_right',
'upper_edge', 'lower_edge' (backend-dependent support).
font_size : int, default: 12
Font size for the text.
color : str, default: "white"
Color of the text.
**kwargs : dict
Additional backend-specific keyword arguments.

Returns
-------
Any
Backend-specific actor or object representing the added text.
"""
raise NotImplementedError("add_text method must be implemented")
Loading
Loading