
.. DO NOT EDIT.
.. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY.
.. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE:
.. "advanced_examples/plot_slope_methods.py"
.. LINE NUMBERS ARE GIVEN BELOW.

.. only:: html

    .. note::
        :class: sphx-glr-download-link-note

        :ref:`Go to the end <sphx_glr_download_advanced_examples_plot_slope_methods.py>`
        to download the full example code

.. rst-class:: sphx-glr-example-title

.. _sphx_glr_advanced_examples_plot_slope_methods.py:


Slope and aspect methods
========================

Terrain slope and aspect can be estimated using different methods.
Here is an example of how to generate the two with each method, and understand their differences.

For more information, see the :ref:`terrain-attributes` chapter and the
:ref:`sphx_glr_basic_examples_plot_terrain_attributes.py` example.

.. GENERATED FROM PYTHON SOURCE LINES 11-16

.. code-block:: default

    import matplotlib.pyplot as plt
    import numpy as np

    import xdem








.. GENERATED FROM PYTHON SOURCE LINES 17-18

**Example data**

.. GENERATED FROM PYTHON SOURCE LINES 18-50

.. code-block:: default


    dem = xdem.DEM(xdem.examples.get_path("longyearbyen_ref_dem"))


    def plot_attribute(attribute, cmap, label=None, vlim=None):
        plt.figure(figsize=(8, 5))

        if vlim is not None:
            if isinstance(vlim, (int, np.integer, float, np.floating)):
                vlims = {"vmin": -vlim, "vmax": vlim}
            elif len(vlim) == 2:
                vlims = {"vmin": vlim[0], "vmax": vlim[1]}
        else:
            vlims = {}

        plt.imshow(
            attribute.squeeze(),
            cmap=cmap,
            extent=[dem.bounds.left, dem.bounds.right, dem.bounds.bottom, dem.bounds.top],
            **vlims
        )
        if label is not None:
            cbar = plt.colorbar()
            cbar.set_label(label)

        plt.xticks([])
        plt.yticks([])
        plt.tight_layout()

        plt.show()









.. GENERATED FROM PYTHON SOURCE LINES 51-53

Slope with method of `Horn (1981) <http://dx.doi.org/10.1109/PROC.1981.11918>`_ (GDAL default), based on a refined
approximation of the gradient  (page 18, bottom left, and pages 20-21).

.. GENERATED FROM PYTHON SOURCE LINES 53-58

.. code-block:: default


    slope_horn = xdem.terrain.slope(dem.data, resolution=dem.res)

    plot_attribute(slope_horn, "Reds", "Slope of Horn (1981) (°)")




.. image-sg:: /advanced_examples/images/sphx_glr_plot_slope_methods_001.png
   :alt: plot slope methods
   :srcset: /advanced_examples/images/sphx_glr_plot_slope_methods_001.png
   :class: sphx-glr-single-img





.. GENERATED FROM PYTHON SOURCE LINES 59-60

Slope with method of `Zevenbergen and Thorne (1987) <http://dx.doi.org/10.1002/esp.3290120107>`_, Equation 13.

.. GENERATED FROM PYTHON SOURCE LINES 60-65

.. code-block:: default


    slope_zevenberg = xdem.terrain.slope(dem.data, resolution=dem.res, method="ZevenbergThorne")

    plot_attribute(slope_zevenberg, "Reds", "Slope of Zevenberg and Thorne (1987) (°)")




.. image-sg:: /advanced_examples/images/sphx_glr_plot_slope_methods_002.png
   :alt: plot slope methods
   :srcset: /advanced_examples/images/sphx_glr_plot_slope_methods_002.png
   :class: sphx-glr-single-img





.. GENERATED FROM PYTHON SOURCE LINES 66-67

We compute the difference between the slopes computed with each method.

.. GENERATED FROM PYTHON SOURCE LINES 67-72

.. code-block:: default


    diff_slope = slope_horn - slope_zevenberg

    plot_attribute(diff_slope, "RdYlBu", "Slope of Horn (1981) minus\n slope of Zevenberg and Thorne (1987) (°)", vlim=3)




.. image-sg:: /advanced_examples/images/sphx_glr_plot_slope_methods_003.png
   :alt: plot slope methods
   :srcset: /advanced_examples/images/sphx_glr_plot_slope_methods_003.png
   :class: sphx-glr-single-img





.. GENERATED FROM PYTHON SOURCE LINES 73-75

The differences are negative, implying that the method of Horn always provides flatter slopes.
Additionally, they seem to occur in places of high curvatures. We verify this by plotting the maximum curvature.

.. GENERATED FROM PYTHON SOURCE LINES 75-80

.. code-block:: default


    maxc = xdem.terrain.maximum_curvature(dem.data, resolution=dem.res)

    plot_attribute(maxc, "RdYlBu", "Maximum curvature (100 m $^{-1}$)", vlim=2)




.. image-sg:: /advanced_examples/images/sphx_glr_plot_slope_methods_004.png
   :alt: plot slope methods
   :srcset: /advanced_examples/images/sphx_glr_plot_slope_methods_004.png
   :class: sphx-glr-single-img





.. GENERATED FROM PYTHON SOURCE LINES 81-83

We quantify the relationship by computing the median of slope differences in bins of curvatures, and plot the
result. We define custom bins for curvature, due to its skewed distribution.

.. GENERATED FROM PYTHON SOURCE LINES 83-101

.. code-block:: default


    df_bin = xdem.spatialstats.nd_binning(
        values=diff_slope[:],
        list_var=[maxc[:]],
        list_var_names=["maxc"],
        list_var_bins=30,
        statistics=[np.nanmedian, "count"],
    )

    xdem.spatialstats.plot_1d_binning(
        df_bin,
        var_name="maxc",
        statistic_name="nanmedian",
        label_var="Maximum absolute curvature (100 m$^{-1}$)",
        label_statistic="Slope of Horn (1981) minus\n " "slope of Zevenberg and Thorne (1987) (°)",
    )





.. image-sg:: /advanced_examples/images/sphx_glr_plot_slope_methods_005.png
   :alt: plot slope methods
   :srcset: /advanced_examples/images/sphx_glr_plot_slope_methods_005.png
   :class: sphx-glr-single-img





.. GENERATED FROM PYTHON SOURCE LINES 102-104

We perform the same exercise to analyze the differences in terrain aspect. We compute the difference modulo 360°,
to account for the circularity of aspect.

.. GENERATED FROM PYTHON SOURCE LINES 104-115

.. code-block:: default


    aspect_horn = xdem.terrain.aspect(dem.data)
    aspect_zevenberg = xdem.terrain.aspect(dem.data, method="ZevenbergThorne")

    diff_aspect = aspect_horn - aspect_zevenberg
    diff_aspect_mod = np.minimum(np.mod(diff_aspect, 360), 360 - np.mod(diff_aspect, 360))

    plot_attribute(
        diff_aspect_mod, "Spectral", "Aspect of Horn (1981) minus\n aspect of Zevenberg and Thorne (1987) (°)", vlim=[0, 90]
    )




.. image-sg:: /advanced_examples/images/sphx_glr_plot_slope_methods_006.png
   :alt: plot slope methods
   :srcset: /advanced_examples/images/sphx_glr_plot_slope_methods_006.png
   :class: sphx-glr-single-img





.. GENERATED FROM PYTHON SOURCE LINES 116-119

Same as for slope, differences in aspect seem to coincide with high curvature areas. We observe also observe large
differences for areas with nearly flat slopes, owing to the high sensitivity of orientation estimation
for flat terrain.

.. GENERATED FROM PYTHON SOURCE LINES 119-121

.. code-block:: default


    # Note: the default aspect for a 0° slope is 180°, as in GDAL.








.. rst-class:: sphx-glr-timing

   **Total running time of the script:** (0 minutes 4.948 seconds)


.. _sphx_glr_download_advanced_examples_plot_slope_methods.py:

.. only:: html

  .. container:: sphx-glr-footer sphx-glr-footer-example




    .. container:: sphx-glr-download sphx-glr-download-python

      :download:`Download Python source code: plot_slope_methods.py <plot_slope_methods.py>`

    .. container:: sphx-glr-download sphx-glr-download-jupyter

      :download:`Download Jupyter notebook: plot_slope_methods.ipynb <plot_slope_methods.ipynb>`


.. only:: html

 .. rst-class:: sphx-glr-signature

    `Gallery generated by Sphinx-Gallery <https://sphinx-gallery.github.io>`_
