Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Geographic north arrow orientation marker #6070

Merged
merged 10 commits into from
Jun 14, 2024
5 changes: 5 additions & 0 deletions pyvista/plotting/plotter.py
Original file line number Diff line number Diff line change
Expand Up @@ -1317,6 +1317,11 @@ def add_box_axes(self, *args, **kwargs): # numpydoc ignore=PR01,RT01
"""Wrap ``Renderer.add_box_axes``."""
return self.renderer.add_box_axes(*args, **kwargs)

@wraps(Renderer.add_north_arrow_widget)
def add_north_arrow_widget(self, *args, **kwargs): # numpydoc ignore=PR01,RT01
"""Wrap ``Renderer.add_north_arrow_widget``."""
return self.renderer.add_north_arrow_widget(*args, **kwargs)

@wraps(Renderer.hide_axes)
def hide_axes(self, *args, **kwargs): # numpydoc ignore=PR01,RT01
"""Wrap ``Renderer.hide_axes``."""
Expand Down
76 changes: 76 additions & 0 deletions pyvista/plotting/renderer.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
from .render_passes import RenderPasses
from .tools import create_axes_marker
from .tools import create_axes_orientation_box
from .tools import create_north_arrow
from .tools import parse_font_family
from .utilities.gl_checks import check_depth_peeling
from .utilities.gl_checks import uses_egl
Expand Down Expand Up @@ -1199,6 +1200,81 @@
axes_widget.SetViewport(viewport)
return self.axes_actor

def add_north_arrow_widget(
self,
interactive=None,
color="#4169E1",
opacity=1.0,
line_width=2,
edge_color=None,
lighting=False,
viewport=(0, 0, 0.1, 0.1),
):
"""Add a geographic north arrow to the scene.

tkoyama010 marked this conversation as resolved.
Show resolved Hide resolved
.. versionadded:: 0.44.0

Parameters
----------
interactive : bool, optional
Control if the orientation widget is interactive. By
default uses the value from
:attr:`pyvista.global_theme.interactive
<pyvista.plotting.themes.Theme.interactive>`.

color : ColorLike, optional
Color of the north arrow.

opacity : float, optional
Opacity of the north arrow.

line_width : float, optional
Width of the north edge arrow lines.

edge_color : ColorLike, optional
Color of the edges.

lighting : bool, optional
Enable or disable lighting on north arrow.

viewport : sequence[float], default: (0, 0, 0.1, 0.1)
Viewport ``(xstart, ystart, xend, yend)`` of the widget.

Returns
-------
vtk.vtkOrientationMarkerWidget
Orientation marker widget.

Examples
--------
Use an north arrow as the orientation widget.

>>> import pyvista as pv
>>> from pyvista import examples
>>> terrain = examples.download_st_helens().warp_by_scalar()
>>> pl = pv.Plotter()
>>> actor = pl.add_mesh(terrain)
>>> widget = pl.add_north_arrow_widget()
>>> pl.enable_terrain_style(True)
>>> pl.show()

"""
marker = create_north_arrow()
mapper = pyvista.DataSetMapper(marker)
actor = pyvista.Actor(mapper)
actor.prop.show_edges = True
if edge_color is not None:
actor.prop.edge_color = edge_color

Check warning on line 1267 in pyvista/plotting/renderer.py

View check run for this annotation

Codecov / codecov/patch

pyvista/plotting/renderer.py#L1267

Added line #L1267 was not covered by tests
actor.prop.line_width = line_width
actor.prop.color = color
actor.prop.opacity = opacity
actor.prop.lighting = lighting
return self.add_orientation_widget(
actor,
interactive=interactive,
viewport=viewport,
)

def add_box_axes(
self,
*,
Expand Down
60 changes: 60 additions & 0 deletions pyvista/plotting/tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -449,6 +449,66 @@ def create_axes_orientation_box(
return actor


def create_north_arrow():
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This may be better as an example mesh rather than a tool here

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Personally, this looks tool.

"""Create a north arrow mesh.

.. versionadded:: 0.44.0

Returns
-------
pyvista.PolyData
North arrow mesh.

"""
points = np.array(
[
[0.0, 5.0, 0.0],
[-2.0, 0.0, 0.0],
[0.0, 1.5, 0.0],
[2.0, 0.0, 0.0],
[0.0, 5.0, 1.0],
[-2.0, 0.0, 1.0],
[0.0, 1.5, 1.0],
[2.0, 0.0, 1.0],
],
)
faces = np.array(
[
4,
3,
7,
4,
0,
4,
2,
6,
7,
3,
4,
1,
5,
6,
2,
4,
0,
4,
5,
1,
4,
0,
1,
2,
3,
4,
4,
7,
6,
5,
],
)
return pyvista.PolyData(points, faces)


def normalize(x, minimum=None, maximum=None):
"""
Normalize the given value between [minimum, maximum].
Expand Down
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added tests/plotting/image_cache/add_north_arrow.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 7 additions & 0 deletions tests/plotting/test_plotting.py
Original file line number Diff line number Diff line change
Expand Up @@ -1227,6 +1227,13 @@ def test_add_box_axes():
plotter.show()


def test_add_north_arrow():
plotter = pv.Plotter()
plotter.add_north_arrow_widget(viewport=(0, 0, 0.5, 0.5))
plotter.add_mesh(pv.Arrow(direction=(0, 1, 0)))
plotter.show()


def test_screenshot(tmpdir):
plotter = pv.Plotter()
plotter.add_mesh(pv.Sphere())
Expand Down