{ "cells": [ { "cell_type": "markdown", "metadata": { "nbsphinx": "hidden" }, "source": [ "This notebook is part of the `kikuchipy` documentation https://kikuchipy.org.\n", "Links to the documentation won't work from the notebook." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Visualizing patterns\n", "\n", "The [EBSD](../reference.rst#kikuchipy.signals.EBSD) and\n", "[EBSDMasterPattern](../reference.rst#kikuchipy.signals.EBSDMasterPattern) signals\n", "have a powerful and versatile\n", "[plot()](http://hyperspy.org/hyperspy-doc/current/api/hyperspy.signal.html#hyperspy.signal.BaseSignal.plot)\n", "method provided by HyperSpy. Its uses are greatly detailed in HyperSpy's\n", "[visualisation user guide](http://hyperspy.org/hyperspy-doc/current/user_guide/visualisation.html).\n", "This section details example uses specific to EBSD and EBSDMasterPattern\n", "signals.\n", "\n", "Let's import the necessary libraries and a Nickel EBSD test data set\n", "Ă…nes et al. (2019):" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Exchange inline for notebook or qt5 (from pyqt) for interactive plotting\n", "%matplotlib inline\n", "\n", "import hyperspy.api as hs\n", "import kikuchipy as kp\n", "import matplotlib.pyplot as plt\n", "import numpy as np\n", "from orix import io, plot, quaternion, vector\n", "import skimage.exposure as ske\n", "import skimage.transform as skt\n", "\n", "\n", "# Use kp.load(\"data.h5\") to load your own data\n", "s = kp.data.nickel_ebsd_large(allow_download=True) # External download\n", "s" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Navigate in custom map\n", "\n", "Correlating results from e.g. crystal and phase structure determination, i.e.\n", "indexing, with experimental patterns can inform their interpretation. When\n", "calling `plot()` without any input parameters, the navigator map is a grey scale\n", "image with pixel values corresponding to the sum of all detector intensities\n", "within that pattern:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "s.plot()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The upper panel shows the navigation axes, in this case 2D, with the current\n", "beam position in the upper left corner shown as a red square the size of one\n", "pixel. This square can be made larger/smaller with +/-.\n", "The square can be moved either by the keyboard arrows or the mouse. The lower\n", "panel shows the image on the detector in the current beam position." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Any\n", "[BaseSignal](http://hyperspy.org/hyperspy-doc/current/api/hyperspy.signal.html#hyperspy.signal.BaseSignal)\n", "signal with a 2D `signal_shape` corresponding to the scan\n", "`navigation_shape` can be passed in to the `navgiator` parameter in\n", "[plot()](http://hyperspy.org/hyperspy-doc/current/api/hyperspy.signal.html#hyperspy.signal.BaseSignal.plot),\n", "including a virtual image showing diffraction contrast, any quality metric map,\n", "or an orientation map or a phase map." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Virtual image" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "A virtual backscatter electron (VBSE) image created from any detector region of\n", "interest with the\n", "[get_virtual_bse_intensity()](../reference.rst#kikuchipy.signals.EBSD.get_virtual_bse_intensity)\n", "method or\n", "[get_rgb_image()](../reference.rst#kikuchipy.generators.VirtualBSEGenerator.get_rgb_image)\n", "explained in the\n", "[virtual backscatter electron imaging](virtual_backscatter_electron_imaging.rst)\n", "section, can be used as a navigator for a scan `s`:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "vbse_gen = kp.generators.VirtualBSEGenerator(s)\n", "print(vbse_gen)\n", "print(vbse_gen.grid_shape)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "vbse_rgb = vbse_gen.get_rgb_image(r=(3, 1), b=(3, 2), g=(3, 3))\n", "vbse_rgb" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "s.plot(navigator=vbse_rgb, cmap=\"viridis\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Any image\n", "\n", "Images loaded into a\n", "[Signal2D](http://hyperspy.org/hyperspy-doc/current/api/hyperspy._signals.signal2d.html#hyperspy._signals.signal2d.Signal2D)\n", "can be used as navigators, like a quality metric map like the\n", "[image quality map](feature_maps.ipynb#Image-quality) calculated using\n", "[get_image_quality()](../reference.rst#kikuchipy.signals.EBSD.get_image_quality):" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "s.remove_static_background()\n", "s.remove_dynamic_background()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "iq = s.get_image_quality()\n", "s_iq = hs.signals.Signal2D(iq)\n", "s.plot(navigator=s_iq, scalebar=False)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Using colour images (apart from creating RGB virtual BSE images, as shown\n", "above), e.g. an orientation map, `om`, or phase map, is a bit more involved\n", "(especially when the image doesn't have the correct pixel shape, as is the case\n", "for our orientation map below, exported from MTEX):" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "om = plt.imread('../_static/image/visualizing_patterns/om.png')\n", "print(om.shape, om.dtype)\n", "om_resized = skt.resize(\n", " om,\n", " output_shape=s.axes_manager.navigation_shape[::-1] + (3,),\n", " anti_aliasing=False\n", ")\n", "om_scaled = ske.rescale_intensity(om_resized, out_range=np.uint8)\n", "s_om = hs.signals.Signal2D(om_scaled)\n", "s_om" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "s_om = s_om.transpose(signal_axes=1)\n", "print(s_om, s_om.data.dtype)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "s_om.change_dtype('rgb8')\n", "print(s_om, s_om.data.dtype)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "s.plot(navigator=s_om, colorbar=False)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Plot multiple signals\n", "\n", "HyperSpy provides the function\n", "[plot_signals()](http://hyperspy.org/hyperspy-doc/current/api/hyperspy.drawing.utils.html#hyperspy.drawing.utils.plot_signals)\n", "to plot multiple signals with the same navigator, as explained in their\n", "[user guide](http://hyperspy.org/hyperspy-doc/current/user_guide/visualisation.html#plotting-several-signals).\n", "This enables e.g. plotting of experimental and best matching simulated patterns\n", "side-by-side as a visual inspection of the results of\n", "[pattern matching](pattern_matching.ipynb). To demonstrate this, we'll load\n", "a [CrystalMap](https://orix.readthedocs.io/en/stable/reference.html#crystalmap)\n", "with the best matching orientations of dynamically simulated Ni patterns to\n", "Nickel test data set, and project these patterns onto our detector from a master\n", "pattern" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "xmap = io.load(\"../_static/data/ni_large.h5\")\n", "xmap" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "mp = kp.data.nickel_ebsd_master_pattern_small(projection=\"lambert\")" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "s_best = mp.get_patterns(\n", " rotations=xmap.rotations,\n", " detector=kp.detectors.EBSDDetector(\n", " shape=s.axes_manager.signal_shape[::-1],\n", " pc=[0.421, 0.7794, 0.5049],\n", " sample_tilt=70,\n", " convention=\"tsl\"\n", " ),\n", " energy=20,\n", " dtype_out=s.data.dtype,\n", " compute=True\n", ")\n", "s_best = kp.signals.EBSD(s_best.data.reshape(s.data.shape))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's create a navigator map from the normalized cross-correlation scores" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "ncc = xmap.get_map_data(xmap.scores[:, 0])\n", "s_ncc = hs.signals.Signal2D(ncc)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "hs.plot.plot_signals([s, s_best], navigator=s_ncc)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This documentation cannot do this very nice feature of HyperSpy, for quick\n", "feedback how well the experimental patterns match the simulated ones,\n", "justice: you have to try it out for yourself!" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Plot master patterns\n", "\n", "[EBSDMasterPattern](../reference.rst#kikuchipy.signals.EBSDMasterPattern) signals\n", "can be navigated along their energy axis and/or the their northern/southern\n", "hemisphere. Let's reload the Nickel master pattern used in the previous section,\n", "but this time in the stereographic projection." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Only a single energy, 20 keV\n", "mp_stereo = kp.data.nickel_ebsd_master_pattern_small(\n", " projection=\"stereographic\", hemisphere=\"both\"\n", ")\n", "print(mp_stereo.axes_manager)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "As can be seen from the axes manager, the master pattern has two navigation\n", "axes, a north and south hemisphere, thus, when plotting, we get a slider as a\n", "navigator when plotting:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "nbsphinx-thumbnail": { "tooltip": "Ways to visualize the navigation (scan) and signal (detector) dimensions" }, "tags": [ "nbsphinx-thumbnail" ] }, "outputs": [], "source": [ "mp_stereo.plot()" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.9.6" } }, "nbformat": 4, "nbformat_minor": 4 }