.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "examples/plotting/visualizing_orientations.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note :ref:`Go to the end ` to download the full example code. .. rst-class:: sphx-glr-example-title .. _sphx_glr_examples_plotting_visualizing_orientations.py: ======================== Visualizing orientations ======================== This example shows how to visualize orientations using various projections. Visualizing orientations requires defining some projection between orientation space and Euclidean space, which will by necessity introduce distortion. This problem is similar to how any 2D map of Earth's surface will always have a spatially-dependent scalebar. Three 3D projections representing orientations as axis-angle pairs are available. Additionally, a 2D projection, given a sample direction, in the stereographic projection is available. The three axis-angle projections, sometimes called Neo-Eulerian projections, describe a rotation by a twist :math:`\omega` around an axis :math:`\hat{\mathbf{n}}`. The :math:`(x, y, z)` coordinates of the rotation's projection are the :math:`(v_x, v_y, v_z)` coordinates of a unit vector describing :math:`\hat{\mathbf{n}}`, scaled by a function of :math:`\omega`. The scaling options are: * axis-angle pair: a linear projection :math:`\omega \cdot \hat{\mathbf{n}}`. Available in :class:`~orix.plot.AxAnglePlot`. * Rodrigues vector: a rectilinear projection :math:`\tan\omega/2 \cdot \hat{\mathbf{n}}`, where rotations sharing a common rotation axis are linearly aligned. Available in :class:`~orix.plot.RodriguesPlot`. * homochoric vector: an equal-volume projection :math:`0.75(\omega-\sin\omega)^{\frac{1}{3}} \cdot \hat{\mathbf{n}}`, where a cube anywhere inside takes up an identical solid angle in rotation space. Available in :class:`~orix.plot.HomochoricPlot`. Note that this list is not exhaustive and that the descriptions are simplified. For a deeper dive into the advantages and disadvantages of these projections, as well as enlightening comparisons of their warping of orientation space, refer to the :cite:`krakow2017onthree`. The 2D projection in the stereographic projection is the so-called inverse pole figure (IPF). This shows which crystal direction :math:`\mathbf{t} = \left` a given sample direction :math:`\mathbf{v} = (x, y, z)` is parallel to. The crystal direction is given in the fundamental sector of an orientations point group and projected down to the equatorial plane using the stereographic projection :math:`(X, Y) = (v_x / (1 - v_z), v_y / (1 - v_z))`. This is computationally efficient and translates well to print publication. However, the projection loses orientation information perpendicular to the sample direction plotted, a bit like a 2D X-ray of a skeleton. The projections are implemented by subclassing Matplotlib's :class:`matplotlib.axes.Axes` and :class:`mpl_toolkits.mplot3d.axes3d.Axes3D`. .. GENERATED FROM PYTHON SOURCE LINES 72-90 .. code-block:: Python import matplotlib.pyplot as plt import numpy as np from orix.plot import IPFColorKeyTSL, register_projections from orix.quaternion import Orientation, OrientationRegion from orix.quaternion.symmetry import D3 register_projections() # Register our custom Matplotlib projections np.random.seed(2319) # Create reproducible random data n = 30 ori = Orientation.random(n, symmetry=D3) # Create an orientation-dependent colormap for more informative plots color_key = IPFColorKeyTSL(D3) rgb = color_key.orientation2color(ori) .. GENERATED FROM PYTHON SOURCE LINES 91-93 Orientation plots can be made in one of two ways. The first and simplest is via :meth:`~orix.quaternion.Orientation.scatter`. .. GENERATED FROM PYTHON SOURCE LINES 93-104 .. code-block:: Python fig = plt.figure(figsize=(12, 3), layout="tight") ori.scatter(c=rgb, position=141, projection="axangle", figure=fig) fig.axes[0].set_title("Axis-Angle Projection") ori.scatter(c=rgb, position=142, projection="rodrigues", figure=fig) fig.axes[1].set_title("Rodrigues Projection") ori.scatter(c=rgb, position=143, projection="homochoric", figure=fig) fig.axes[2].set_title("Homochoric Projection") ori.scatter(c=rgb, position=144, projection="ipf", figure=fig) _ = fig.axes[3].set_title("Inverse Pole Figure Projection \n\n") .. image-sg:: /examples/plotting/images/sphx_glr_visualizing_orientations_001.png :alt: Axis-Angle Projection, Rodrigues Projection, Homochoric Projection, Inverse Pole Figure Projection :srcset: /examples/plotting/images/sphx_glr_visualizing_orientations_001.png :class: sphx-glr-single-img .. GENERATED FROM PYTHON SOURCE LINES 105-106 This can also be used to create standalone figures .. GENERATED FROM PYTHON SOURCE LINES 106-109 .. code-block:: Python ori.scatter(c=rgb, projection="ipf") .. image-sg:: /examples/plotting/images/sphx_glr_visualizing_orientations_002.png :alt: z :srcset: /examples/plotting/images/sphx_glr_visualizing_orientations_002.png :class: sphx-glr-single-img .. GENERATED FROM PYTHON SOURCE LINES 110-117 The second method is by setting the projections when defining the Matplotlib axes. This can require more tinkering since the plots are not auto-formatted like above, but it allows for more customization as well as the plotting of multiple datasets on a single plot Additionally, for these plots, we will set the scaling equivalent in order to better illustrate the differences in the scales of the Neo-Eulerian plotting methods. .. GENERATED FROM PYTHON SOURCE LINES 117-139 .. code-block:: Python fig = plt.figure(figsize=(12, 3), layout="constrained") ax_ax = fig.add_subplot(141, projection="axangle") ax_rod = fig.add_subplot(142, projection="rodrigues") ax_hom = fig.add_subplot(143, projection="homochoric") ax_ipf = fig.add_subplot(144, projection="ipf", symmetry=D3) ax_ipf.scatter(ori, c=rgb) ax_ax.set_title("Axis-Angle Projection") ax_rod.set_title("Rodrigues Projection") ax_hom.set_title("Homochoric Projection") ax_ipf.set_title("Inverse Pole Figure Projection \n\n") fundamental_zone = OrientationRegion.from_symmetry(ori.symmetry) for ax in [ax_ax, ax_rod, ax_hom]: ax.plot_wireframe(fundamental_zone) ax.set_proj_type = "ortho" ax.axis("off") ax.set(xlim=(-1.2, 1.2), ylim=(-1.2, 1.2), zlim=(-1.2, 1.2)) ax.scatter(ori, c=rgb) .. image-sg:: /examples/plotting/images/sphx_glr_visualizing_orientations_003.png :alt: Axis-Angle Projection, Rodrigues Projection, Homochoric Projection, Inverse Pole Figure Projection :srcset: /examples/plotting/images/sphx_glr_visualizing_orientations_003.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 1.585 seconds) **Estimated memory usage:** 553 MB .. _sphx_glr_download_examples_plotting_visualizing_orientations.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: visualizing_orientations.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: visualizing_orientations.py ` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: visualizing_orientations.zip ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_