Skip to content
Merged
Show file tree
Hide file tree
Changes from 18 commits
Commits
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
1 change: 1 addition & 0 deletions doc/changelog.d/466.miscellaneous.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Feat: more customization APIs
30 changes: 27 additions & 3 deletions examples/00-basic-pyvista-examples/customization_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,12 +83,36 @@


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

# Additional labels at the top corners
plotter.add_text("Plotly Backend", position=(0.05, 0.95), font_size=12, color='lightblue')
# Additional labels at the top left corner using a string for the position as before
plotter.add_text("PyVista Backend", position="upper_left", font_size=12, color='lightblue')
# Additional labels at the bottom left corner using pixel coordinates
plotter.add_text("3D Visualization", position=(0.95, 0.95), font_size=12, color='lightgreen')


# Add labels at specific 3D points to annotate key locations in space.

label_points = [
[1, 0, 0], # X axis endpoint
[0, 1, 0], # Y axis endpoint
[0, 0, 1], # Z axis endpoint
]

labels = ['X-axis', 'Y-axis', 'Z-axis']

plotter.add_labels(label_points, labels, font_size=16, point_size=8.0)


# The clear() method resets the plotter and can be called even after show().
# This allows reusing the same plotter for multiple visualizations.

# Uncomment to clear everything added above and start fresh:
# plotter.show()
# plotter.clear()
# plotter.plot(pv.Cube()) # Would show only a cube instead
Comment thread
RobPasMue marked this conversation as resolved.


# Display the visualization with all customizations.

plotter.show()
24 changes: 23 additions & 1 deletion examples/01-basic-plotly-examples/customization_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,13 +86,35 @@
# 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')
plotter.add_text("Customization API Example", position=(0.5, 0.95), font_size=18, color='black')

# 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')


# Add labels at specific 3D points to annotate key locations in space.

label_points = [
[1, 0, 0], # X axis endpoint
[0, 1, 0], # Y axis endpoint
[0, 0, 1], # Z axis endpoint
]

labels = ['X-axis', 'Y-axis', 'Z-axis']

plotter.add_labels(label_points, labels, font_size=16, point_size=8.0)


# The clear() method resets the plotter and can be called even after show().
# This allows reusing the same plotter for multiple visualizations.

# Uncomment to clear everything added above and start fresh:
# plotter.show()
# plotter.clear()
# plotter.plot(pv.Cube()) # Would show only a cube instead
Comment thread
RobPasMue marked this conversation as resolved.


# Display the visualization with all customizations.


Expand Down
51 changes: 51 additions & 0 deletions src/ansys/tools/visualization_interface/backends/_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -170,3 +170,54 @@ def add_text(
Backend-specific actor or object representing the added text.
"""
raise NotImplementedError("add_text method must be implemented")

@abstractmethod
def add_labels(
self,
points: Union[List, Any],
labels: List[str],
font_size: int = 12,
point_size: float = 5.0,
**kwargs
) -> Any:
"""Add labels at 3D point locations.

Parameters
----------
points : Union[List, Any]
Points where labels should be placed. Can be a list of coordinates
or array-like object. Expected format: [[x1, y1, z1], ...] or Nx3 array.
labels : List[str]
List of label strings to display at each point.
font_size : int, default: 12
Font size for the labels.
point_size : float, default: 5.0
Size of the point markers shown with labels.
**kwargs : dict
Additional backend-specific keyword arguments.

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

@abstractmethod
def clear(self) -> None:
"""Clear all actors from the scene.

This method removes all previously added objects (meshes, points, lines,
text, etc.) from the visualization scene, therefore allowing
the plotter to be reused after ``show()`` has been called.

Notes
-----
Both PyVista and Plotly backends support clearing and reusing the
plotter after ``show()`` has been called. This enables workflows like:

1. Add objects and call ``show()``
2. Call ``clear()`` to reset
3. Add new objects and call ``show()`` again
"""
raise NotImplementedError("clear method must be implemented")
Original file line number Diff line number Diff line change
Expand Up @@ -494,3 +494,55 @@ def add_text(
)
self._fig.add_annotation(annotation)
return annotation

def add_labels(
self,
points: Union[List, Any],
labels: List[str],
font_size: int = 12,
point_size: float = 5.0,
**kwargs
) -> Any:
"""Add labels at 3D point locations.

Parameters
----------
points : Union[List, Any]
Points where labels should be placed.
labels : List[str]
List of label strings to display at each point.
font_size : int, default: 12
Font size for the labels.
point_size : float, default: 5.0
Size of the point markers shown with labels.
**kwargs : dict
Additional keyword arguments.

Returns
-------
Any
Plotly trace representing the labels.
"""
import numpy as np

points_array = np.asarray(points)
if points_array.ndim == 1:
points_array = points_array.reshape(-1, 3)

# Create a scatter trace with both markers and text
trace = go.Scatter3d(
x=points_array[:, 0],
y=points_array[:, 1],
z=points_array[:, 2],
mode='markers+text',
text=labels,
textfont=dict(size=font_size),
marker=dict(size=point_size),
**kwargs
)
self._fig.add_trace(trace)
return trace

def clear(self) -> None:
"""Clear all traces from the figure."""
self._fig.data = []
Loading
Loading