Skip to content

Python tools for visualizing 3D angles, shapes and histograms on the unit sphere with matplotlib.

License

Notifications You must be signed in to change notification settings

rfayat/angle_visualization

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

23 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Angle visualization

A few python tools for visualizing 3D angles, shapes and histograms on the unit sphere with matplotlib.

Installation

Installation with pip

Using a python>=3.6 environment, simply clone the repository and install it with pip:

$ git clone https://github.com/rfayat/angle_visualization.git
$ cd angle_visualization
$ pip install .

Troubleshooting

The installation pipeline was tested on ubuntu 20.04 and should be working fine on linux. The module cartopy is however a dependency for plotting 2D projections of the sphere and might cause hurdles during installation especially on windows and MacOS. Try following cartopy's installation guidelines if it is the case. One potential source of issues is the dependency of cartopy on GEOS, an open source C++ geometry engine which will probably need to be installed independently.

Figure generation

To generate the figures shown below, install the additional requirement (seaborn), uncomment the desired function at the end of this script (after if __name__=="__main__":) and run:

$ python -m README_figures.generate_figures

Delaunay triangulation of a Fibonacci sphere

Complete Delaunay triangulation for 3D shapes

An extension of scipy's Delaunay triangulation routine, (angle_visualization.triangulation.Delaunay_Complete), allows to obtain a triangulation of closed 3D objects. The triangulation can be performed using a 2D array containing the x, y and z coordinates of the vertices with shape (n_vertices, 3):

# Generate the coordinates of a Fibonacci sphere with n_points points
from angle_visualization.triangulation import Delaunay_Complete
# vertices is an array of shape (n_vertices, 3)
triangulated = angle_visualization.triangulation.Delaunay_Complete(vertices)

A comparison of the triangulation resulting from scipy's routine and its extension is shown below. The corresponding code can be found in generate_figures.py (plot_triangulated_cube function):

Delaunay_cube

Triangulated Fibonacci sphere

Fibonacci sphere

The euclidean coordinates of a Fibonacci sphere can be generated using angle_visualization.triangulation.fibonacci_sphere,

# Generate the coordinates of a Fibonacci sphere with n_points points
from angle_visualization.triangulation import fibonacci_sphere
n_points = 1000
x, y, z = fibonacci_sphere(n_points)

Fibonacci_Sphere

Generating a triangulated Fibonacci sphere

A triangulated Fibonacci sphere with n_points=3000 vertices can be generated as follows:

from angle_visualization.triangulation import Delaunay_Sphere
# Delaunay triangulation of the sphere
n_points = 3000
d = Delaunay_Sphere(n_points)

It has among others properties storing the edges (Delaunay_Sphere.edges), faces (Delaunay_Sphere.faces) and face centroids (Delaunay_Sphere.face_centroids) coordinates as numpy arrays.

Visualization

The facets of the Delaunay sphere can be visualized using angle_visualization.plot_faces as follows:

import angle_visualization
import angle_visualization.triangulation
# Create a triangulated Fibonacci sphere with 3000 vertices
n_points = 3000
d = angle_visualization.triangulation.Delaunay_Sphere(n_points)

# Plot the result
fig = plt.figure(figsize=(4, 4))
ax = fig.add_subplot(111, projection='3d')
angle_visualization.plot_faces(d.faces,
                               ax=ax,
                               linewidths=...,
                               face_colors=...,
                               edge_colors=...)

An example for plotting faces with colors depending on the face centroids' coordinates can be found in generate_figures.py (plot_triangulated_sphere function):

Triangulated_Fibonacci_Sphere

Angle histogram on a sphere

3D angle histogram on a Fibonacci sphere

The Delaunay_Sphere can allocate each element of a 2D array with shape (n_arrays, 3) where axis 1 corresponds to the x, y and z coordinates of vectors on the unit sphere as follows:

import angle_visualization
import angle_visualization.triangulation
# Create a triangulated Fibonacci sphere with 3000 vertices
n_points = 3000
d = angle_visualization.triangulation.Delaunay_Sphere(n_points)
# Compute the histogram on the sphere for the input array data
# data is a 2D array of unit 3D vectors with shape (n_arrays, 3)
triangle_idx_all, counts = d.spherical_histogram(data)

After converting the counts to a colorscale, the resulting histogram on the unit sphere can be visualized using the angle_visualization.plot_faces function. An example can be found in generate_figures.py (plot_histogram_3D function):

histogram_3D

2D projection of the sphere

Leveraging cartopy's functionalities, the resulting histogram on the unit sphere can be projected in 2D using the angle_visualization.fill_projected_faces_euclidean function. For instance, using the outputs of Delaunay_Sphere.spherical_histogram, a Lambert Azimuthal Equal-Area (LAEA) projection of the histogram can be visualized as follows:

# Create the projected axis using cartopy
fig = plt.figure(figsize=(4, 4))
projection = angle_visualization.LAEA  # Lambert Azimuthal Equal-Area projection  # noqa
ax = fig.add_subplot(1, 1, 1, projection=projection)
ax.gridlines()

# Plot the projected faces
angle_visualization.fill_projected_faces_euclidean(
    *d.faces.transpose(2, 0, 1), face_colors=..., alpha=1
)

An example can be found in generate_figures.py (plot_projected_histogram_3D function) and results in:

projected_histogram_3D

Other 3D-shapes

Sphere

# Plot a sphere
sphere = angle_visualization.shapes.Sphere3D.add_sphere(
    radius=1.,
    origin=[0, 0, 0],
    steps=30,
    ax=ax, color="blue", alpha=.7,
)

sphere

Arrows

angle_visualization.shapes.Arrow3D inherits from matplotlib's FancyArrowPatch. Plotting a single arrow an xyz origin can be done as follows:

# Plot a single 3-dimensional arrow
arrow = angle_visualization.shapes.Arrow3D.add_arrow(
    2, .3, 3,
    origin=[-.5, 0, -1],
    color="purple",
    mutation_scale=20,
    arrowstyle="-|>",
    lw=5,
    adjust_ax_lim=False,
    ax=ax
)

# Plot an xyz origin in 3D
xyz = angle_visualization.shapes.Arrow3D.add_xyz(
    V=np.eye(3),
    origin=[0, 0, 0],
    mutation_scale=10,
    arrowstyle="-|>",
    lw=3,
    adjust_ax_lim=False,
    ax=ax
)

arrows

Rotations / Quaternions

Not implemented yet. The idea here would be to have a simple way to visualize unit quaternions / rotations (axis and magnitude) using matplotlib similarly to WolframAlpha's representation of rotations, taking as input a scipy Rotation object.

If you feel like developing this functionality, don't hesitate opening a pull request or having a look at the (very) preliminary angle_visualization.shapes.Quaternion3D class, I'd be glad to help.

About

Python tools for visualizing 3D angles, shapes and histograms on the unit sphere with matplotlib.

Topics

Resources

License

Stars

Watchers

Forks

Languages