All user facing changes to this project are documented in this file. The format is based on Keep a Changelog, and this project tries its best to adhere to Semantic Versioning.

2023-03-14 - version 0.11.1#


  • Initialization of a crystal map with a phase list with fewer phases than in the phase ID array given returns a map with a new phase list with correct phase IDs.

2023-02-09 - version 0.11.0#


  • Creation of one or more Quaternion (or instances of inheriting classes) from one or more SciPy Rotation.

  • Creation of one Quaternion or Rotation by aligning sets of vectors in two reference frames, one Orientation by aligning sets of sample vectors and crystal vectors, and one Misorientation by aligning two sets of crystal vectors in two different crystals.

  • row and col properties to CrystalMap giving the row and column coordinate of each map point given by CrystalMap.shape.

  • Rotation class methods from_neo_euler(), from_axes_angles(), from_euler(), from_matrix(), random() and identity() and methods to_euler() and to_matrix() are now available from the Quaternion class as well.

  • StereographicPlot.restrict_to_sector() allows two new parameters to control the amount of padding (in degrees in stereographic projection) and whether to show the sector edges. Keyword arguments can also be passed on to Matplotlib’s PathPatch().

  • Option to pass degrees to the Quaternion methods from_axes_angles(), from_euler() and to_euler() by passing degrees=True.

  • Option to get degrees from all angle_with() and angle_with_outer() methods by passing degrees=True.

  • Option to pass degrees to the (Mis)Orientation method get_distance_matrix() by passing degrees=True.

  • Option to pass degrees to the Vector3d methods from_polar() and to_polar() by passing degrees=True.

  • Option to get spherical coordinates from InverseStereographicProjection.xy2spherical() in degrees or pass them as degrees to StereographicProjection methods spherical2xy() and spherical2xy_split() by passing degrees=True.


  • Bumped minimal version of diffpy.structure >= 3.0.2.

  • Only ASTAR .ang files return crystal maps with "nm" as scan unit.


  • Parameter z when creating a CrystalMap and the z and dz attributes of the class were deprecated in 0.10.1 and are now removed.

  • Passing shape or step_sizes with three values to create_coordinate_arrays() was depreacted in 0.10. and will now raise an error.

  • Parameter depth (and axes) in CrystalMapPlot.plot_map() was depreacted in 0.10.1 and will now raise an error if passed.

  • The z and dz datasets are not present in new orix HDF5 files. They are not read if present in older files.


  • Reading of EDAX TSL .ang files with ten columns should now work.

2022-10-25 - version 0.10.2#


  • Miller.symmetrise(unique=True) returns the correct number of symmetrically equivalent but unique vectors, by rounding to 10 instead of 12 decimals prior to finding the unique vectors with NumPy.


  • Unique rotations and vectors are now found by rounding to 10 instead of 12 decimals.

2022-10-03 - version 0.10.1#


  • Parameter z when creating a CrystalMap and the z and dz attributes of the class are deprecated and will be removed in 0.11.0. Support for 3D crystal maps is minimal and brittle, and it was therefore decided to remove it altogether.

  • Passing shape or step_sizes with three values to create_coordinate_arrays() is depreacted and will raise an error in 0.11.0. See the previous point for the reason.

  • Parameter depth in CrystalMapPlot.plot_map() is depreacted and will be removed in 0.11.0. See the top point for the reason.


  • StereographicPlot.scatter() now accepts both c/color and s/sizes to set the color and sizes of scatter points, in line with matplotlib.axes.Axes.scatter().

  • Indexing/slicing into an already indexed/sliced CrystalMap now correctly returns the index/slice according to CrystalMap.shape and not the original shape of the un-sliced map.

2022-09-22 - version 0.10.0#


  • Support for type hints has been introduced and a section on this topic has been added to the contributing guide.

  • Vector3d.pole_density_function() has been implemented which allows for calculation of the Pole Density Function (PDF) and quantification of poles in the stereographic projection.

  • Seven methods for sampling unit vectors from regular grids on S2 via orix.sampling.sample_S2().

  • Calculation of the Inverse Pole Density Function (IPDF), ie. pole density in the crystal point group fundamental sector, through InversePoleFigurePlot.pole_density_function().

  • The orix.measure module has been introduced. The measure module is related to quantification of orientation and vector data.

  • Plotting the IPF color key on a created InversePoleFigurePlot is now possible with plot_ipf_color_key().

  • Examples gallery to documentation.


  • Moved part of documentation showing plotting of Wulff net and symmetry markers from the tutorials to examples.

  • Renamed user guide notebooks to tutorials in documentation.

  • Reference frame labels of stereographic projection of Symmetry.plot() from (a, b) to (e1, e2), signifying the standard Cartesian reference frame attached to a crystal.

  • Tighten distribution of random orientation clusters in tutorial showing clustering across fundamental region boundaries, to avoid clustering sometimes giving two clusters instead of three.


  • Support for Python 3.6 has been removed. The minimum supported version in orix is now Python 3.7.

  • Object3d.check(), Quaternion.check_quaternion() and Vector3d.check_vector(), as these methods were not used internally.

  • Deprecated method distance() of Misorientation and Orientation classes, use get_distance_matrix() instead.


  • Plotting of unit cells works with Matplotlib v3.6, at the expense of a warning raised with earlier versions.

2022-05-16 - version 0.9.0#


  • Dask computation of Quaternion and Rotation outer() methods through addition of a lazy parameter. This is useful to reduce memory usage when working with large arrays.

  • Dask implementation of the Quaternion - Vector3d outer product.

  • Point group Symmetry elements can now be viewed in the stereographic projection using Symmetry.plot(). The notebook point_groups.ipynb has been added to the documentation.

  • Add reproject argument to Vector3d.scatter() which reprojects vectors located on the hidden hemisphere to the visible hemisphere.

  • reproject argument to Vector3d.draw_circle() which reprojects parts of circle(s) on the other hemisphere to the current hemisphere.

  • Rotation objects can now be checked for equality. Equality is determined by comparing their shape, data, and whether the rotations are improper.

  • angle_with_outer() has been added to both Rotation and Orientation classes which computes the misorientation angle between every Rotation in the two sets of rotations. In the case of Orientation.angle_with_outer(), this is the symmetry reduced misorientation.

  • Notebook on clustering of misorientations across fundamental region boundaries moved from the orix-demos repository to the user guide.

  • module with test data used in the user guide and tests.

  • Misorientation.get_distance_matrix() for memory-efficient calculation of a misorientation angle (geodesic distance) matrix between misorientations using Dask.

  • Clarification of crystal axes alignment in documentation.

  • Creation of a Phase instance from a CIF file.


  • from_euler() method of Rotation-based classes now interprets angles in Bunge convention by default, ie. direction="lab2crystal". The returned Rotation from this function may be inverted from prior releases and users are advised to check their code.

  • The direction parameter in from_euler() methods, in addition to "lab2crystal" (now default) and "crystal2lab", now also accepts a convenience argument "mtex" which is consistent with the "crystal2lab" direction in MTEX.

  • S4 (-4) Symmetry has been corrected.

  • Organized user guide documentation into topics.


  • The convention parameter in from_euler() and to_euler() methods has been deprecated, in favour of direction in the former. This parameter will be removed in release 1.0.

  • Misorientation.distance() in favour of Misorientation.get_distance_matrix().


  • Fixed bug in sample_S2_uv_mesh() and removed duplicate vectors at poles.

  • The results from Orientation.dot_outer() are now returned as self.shape + other.shape, which is consistent with Rotation.dot_outer().

  • Writing of property arrays in .ang writer from masked CrystalMap.


  • orix.scalar.Scalar class has been removed and the data held by Scalar is now returned directly as a numpy.ndarray.

  • The deprecation of function (Mis)Orientation.set_symmetry() and property Object3d.data_dim has expired and have been removed.

2022-02-21 - version 0.8.2#


  • orix.quaternion.Quaternion now relies on numpy-quaternion for quaternion conjugation, quaternion-quaternion and quaternion-vector multiplication, and quaternion-quaternion and quaternion-vector outer products.

  • Rounding in functions, e.g. Object3d.unique() and Rotation.unique(), is now set consistently at 12 dp.


  • Miller.in_fundamental_sector() doesn’t raise errors.

  • Miller.unique() now correctly returns unique vectors due to implemented rounding.

2022-02-14 - version 0.8.1#


  • Python 3.10 support.

  • Option to pass figure initialization keyword arguments to Matplotlib via plotting methods.


  • Orientation disorientation angles and dot products returned from angle_with() and dot() and dot_outer(), which now calculates the misorientation as other * ~self. Disorientation angles (o2 - o1).angle and o1.angle_with(o2) are now the same.

  • The inverse indices returned from Rotation.unique() now correctly recreate the original Rotation instance.

  • Handling of property arrays in .ang writer with multiple values per map point.

  • CrystalMap’s handling of a mask of which points are in the data.

2021-12-21 - version 0.8.0#


  • FundamentalSector class of vector normals describing a fundamental sector in the stereographic projection, typically the inverse pole figure of a Symmetry.

  • Symmetry.fundamental_sector attribute with a FundamentalSector for that symmetry.

  • StereographicPlot.restrict_to_sector() to restrict the stereographic projection to a sector, typically the inverse pole figure of a Symmetry.

  • StereographicPlot.stereographic_grid() to control the azimuth and polar grid lines.

  • Sampling of vectors in UV mesh on a unit sphere (S2).

  • ndim attribute to Object3d and derived classes which returns number of navigation dimensions.

  • Setting the symmetry of a (Mis)Orientation via a symmetry.setter.

  • Projection of vectors into the fundamental sector (inverse pole figure) of a symmetry.

  • Plotting of orientations within an inverse pole figure given a Laue symmetry and sample direction.

  • Inverse pole figure colouring of orientations given a Laue symmetry and sample direction.

  • from_axes_angles() method to Rotation and Orientation as a shortcut to from_neo_euler() for axis/angle pairs.

  • Orientation based classes now accept a symmetry argument upon initialisation.

  • Euler angle colouring of orientations given a proper point group symmetry.

  • Simple unit cell orientation plotting with plot_unit_cell for Orientation instances.


  • StereographicPlot doesn’t use Matplotlib’s transforms framework anymore, and (X, Y) replaces (azimuth, polar) as internal coordinates.

  • Renamed Symmetry method fundamental_sector() to fundamental_zone().

  • Orientation class methods from_euler, from_matrix, and from_neo_euler no longer return the smallest angle orientation when a symmetry is given.

  • CrystalMap.orientations no longer returns smallest angle orientation.

  • The methods flatten, reshape, and squeeze have been overridden in Misorientation based classes to maintain the initial symmetry of the returned instance.

  • Rotation.to_euler() returns angles in the ranges (0, 2 pi), (0, pi), and (0, 2 pi).

  • CrystalMap.get_map_data() doesn’t round values by default anymore. Passing decimals=3 retains the old behaviour.

  • CrystalMap.plot() doesn’t override the Matplotlib status bar by default anymore. Passing override_status_bar=True retains the old behaviour.


  • The data_dim attribute of Object3d and all derived classes is deprecated from 0.8 and will be removed in 0.9. Use ndim instead.

  • Setting (Mis)Orientation symmetry via set_symmetry() is deprecated in 0.8, in favour of setting it directly via a symmetry.setter, and will be removed in 0.9. Use map_into_symmetry_reduced_zone() instead.


  • StereographicPlot methods azimuth_grid() and polar_grid(). Use stereographic_grid() instead.

  • from_euler() no longer accepts "Krakow_Hielscher" as a convention, use "MTEX" instead.


  • CrystalMap.get_map_data() can return an array of shape (3,) if there are that many points in the map.

  • Reading of point groups with “-” sign, like -43m, from EMsoft h5ebsd files.

2021-09-07 - version 0.7.0#


  • Memory-efficient calculation of a misorientation angle (geodesic distance) matrix between orientations using Dask.

  • Symmetry reduced calculations of dot products between orientations.

  • Two notebooks on clustering of orientations (not misorientations) across fundamental region boundaries are added to the user guide from the orix-demos repository.

  • Convenience method Misorientation.scatter() (and subclasses) to plot orientations in either axis-angle or Rodrigues fundamental zone.

  • Method Object3d.get_random_sample(), inherited by all 3D objects, returning a new flattened instance with elements drawn randomly from the original instance.

  • Add transpose() method to all 3D classes to transpose navigation dimensions.

  • Reading of a CrystalMap from orientation data in Bruker’s HDF5 file format.

  • Uniform sampling of orientation space using cubochoric sampling.


  • to_euler() changed internally, “Krakow_Hielscher” deprecated, use “MTEX” instead.

  • Default orientation space sampling method from “haar_euler” to “cubochoric”.

2021-05-23 - version 0.6.0#


  • Python 3.9 support.

  • User guide with Jupyter notebooks as part of the Read the Docs documentation.

  • CrystalMap.plot() method for easy plotting of phases, properties etc.

  • .ang file writer for CrystalMap objects (via

  • Miller class, inheriting functionality from the Vector3d class, to handle operations with direct lattice vectors (uvw/UVTW) and reciprocal lattice vectors (hkl/hkil).

  • Vector3d.scatter() and Vector3d.draw_circle() methods to show unit vectors and great/small circles in stereographic projection.

  • Stereographic plot using Matplotlib’s transforms framework for plotting vectors, great/small circles, and symmetry elements.

  • projections module for projecting vectors to various coordinates, including stereographic coordinates.

  • CrystalMap.empty() class method to create empty map of a given shape with identity rotations.

  • Sampling of SO(3) now provided via two methods (up from the one in previous versions).

  • Warning when trying to create rotations from large Euler angles.

  • Passing symmetry when initializing an Orientation.

  • Overloaded division for Vector3d (left hand side) by numbers and suitably shaped array-like objects.


  • Names of spherical coordinates for the Vector3d class, phi to azimuth, theta to polar, and r to radial. Similar changes to to/from_polar parameter names.

  • CrystalMap.get_map_data() tries to respect input data type, other minor improvements.

  • Continuous integration migrated from Travis CI to GitHub Actions.


  • Symmetry is preserved when creating a misorientation from orientations or when inverting orientations.

  • Reading of properties (scores etc.) from EMsoft h5ebsd files with certain map shapes.

  • Reading of crystal symmetry from EMsoft h5ebsd dot product files in CrystalMap plugin.

2020-11-03 - version 0.5.1#


  • This project now keeps a Changelog.

  • Testing for Python 3.8 on macOS.


  • CrystalMap properties allow arrays with number of dimensions greater than 2.

  • .ang file reader now recognises phase IDs defined in the header.

  • EMsoft file reader reads unrefined Euler angles correctly.