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

.. only:: html

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

        :ref:`Go to the end <sphx_glr_download_tutorial_08_widgets_g_sphere-widget.py>`
        to download the full example code. or to run this example in your browser via Binder

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

.. _sphx_glr_tutorial_08_widgets_g_sphere-widget.py:


Sphere Widget
~~~~~~~~~~~~~

The sphere widget can be enabled and disabled by the
:func:`pyvista.Plotter.add_sphere_widget` and
:func:`pyvista.Plotter.clear_sphere_widgets` methods respectively.
This is a very versatile widget as it can control vertex location that can
be used to control or update the location of just about anything.

We don't have any convenient helper methods that utilize this widget out of
the box, but we have added a lot of ways to use this widget so that you can
easily add several widgets to a scene.

Let's look at a few use cases that all update a surface mesh.

.. GENERATED FROM PYTHON SOURCE LINES 17-19

.. code-block:: Python
   :dedent: 1










.. GENERATED FROM PYTHON SOURCE LINES 21-25

Example A
+++++++++

Use a single sphere widget

.. GENERATED FROM PYTHON SOURCE LINES 25-53

.. code-block:: Python


    import numpy as np
    import pyvista as pv

    # Create a triangle surface
    surf = pv.PolyData()
    surf.points = np.array(
        [
            [-10, -10, -10],
            [10, 10, -10],
            [-10, 10, 0],
        ]
    )
    surf.faces = np.array([3, 0, 1, 2])

    pl = pv.Plotter()


    def callback(point) -> None:
        surf.points[0] = point


    pl.add_sphere_widget(callback)
    pl.add_mesh(surf, color=True)

    pl.show_grid()
    pl.show()








.. tab-set::



   .. tab-item:: Static Scene



            
     .. image-sg:: /tutorial/08_widgets/images/sphx_glr_g_sphere-widget_001.png
        :alt: g sphere widget
        :srcset: /tutorial/08_widgets/images/sphx_glr_g_sphere-widget_001.png
        :class: sphx-glr-single-img
     


   .. tab-item:: Interactive Scene



       .. offlineviewer:: /home/runner/work/pyvista-tutorial/pyvista-tutorial/doc/source/tutorial/08_widgets/images/sphx_glr_g_sphere-widget_001.vtksz






.. GENERATED FROM PYTHON SOURCE LINES 54-57

And here is a screen capture of a user interacting with this

.. image:: ../../images/gifs/sphere-widget-a.gif

.. GENERATED FROM PYTHON SOURCE LINES 60-64

Example B
+++++++++

Use several sphere widgets at once

.. GENERATED FROM PYTHON SOURCE LINES 64-93

.. code-block:: Python


    import numpy as np
    import pyvista as pv

    # Create a triangle surface
    surf = pv.PolyData()
    surf.points = np.array(
        [
            [-10, -10, -10],
            [10, 10, -10],
            [-10, 10, 0],
        ]
    )
    surf.faces = np.array([3, 0, 1, 2])


    pl = pv.Plotter()


    def callback(point, i) -> None:
        surf.points[i] = point


    pl.add_sphere_widget(callback, center=surf.points)
    pl.add_mesh(surf, color=True)

    pl.show_grid()
    pl.show()








.. tab-set::



   .. tab-item:: Static Scene



            
     .. image-sg:: /tutorial/08_widgets/images/sphx_glr_g_sphere-widget_002.png
        :alt: g sphere widget
        :srcset: /tutorial/08_widgets/images/sphx_glr_g_sphere-widget_002.png
        :class: sphx-glr-single-img
     


   .. tab-item:: Interactive Scene



       .. offlineviewer:: /home/runner/work/pyvista-tutorial/pyvista-tutorial/doc/source/tutorial/08_widgets/images/sphx_glr_g_sphere-widget_002.vtksz






.. GENERATED FROM PYTHON SOURCE LINES 94-97

And here is a screen capture of a user interacting with this

.. image:: ../../images/gifs/sphere-widget-b.gif

.. GENERATED FROM PYTHON SOURCE LINES 99-104

Example C
+++++++++

This one is the coolest - use four sphere widgets to update perturbations on
a surface and interpolate between them with some boundary conditions

.. GENERATED FROM PYTHON SOURCE LINES 104-148

.. code-block:: Python


    from itertools import cycle

    import matplotlib as mpl
    import numpy as np
    import pyvista as pv
    from scipy.interpolate import griddata


    def get_colors(n):
        """A helper function to get n colors."""
        cycler = mpl.rcParams["axes.prop_cycle"]
        colors = cycle(cycler)
        return [next(colors)["color"] for i in range(n)]


    # Create a grid to interpolate to
    xmin, xmax, ymin, ymax = 0, 100, 0, 100
    x = np.linspace(xmin, xmax, num=25)
    y = np.linspace(ymin, ymax, num=25)
    xx, yy, zz = np.meshgrid(x, y, [0])

    # Make sure boundary conditions exist
    boundaries = np.array([[xmin, ymin, 0], [xmin, ymax, 0], [xmax, ymin, 0], [xmax, ymax, 0]])

    # Create the PyVista mesh to hold this grid
    surf = pv.StructuredGrid(xx, yy, zz)

    # Create some initial perturbations
    # - this array will be updated inplace
    points = np.array([[33, 25, 45], [70, 80, 13], [51, 57, 10], [25, 69, 20]])


    # Create an interpolation function to update that surface mesh
    def update_surface(point, i) -> None:
        points[i] = point
        tp = np.vstack((points, boundaries))
        zz = griddata(tp[:, 0:2], tp[:, 2], (xx[:, :, 0], yy[:, :, 0]), method="cubic")
        surf.points[:, -1] = zz.ravel(order="F")


    # Get a list of unique colors for each widget
    colors = get_colors(len(points))








.. GENERATED FROM PYTHON SOURCE LINES 149-164

.. code-block:: Python


    # Begin the plotting routine
    pl = pv.Plotter()

    # Add the surface to the scene
    pl.add_mesh(surf, color=True)

    # Add the widgets which will update the surface
    pl.add_sphere_widget(update_surface, center=points, color=colors, radius=3)
    # Add axes grid
    pl.show_grid()

    # Show it!
    pl.show()








.. tab-set::



   .. tab-item:: Static Scene



            
     .. image-sg:: /tutorial/08_widgets/images/sphx_glr_g_sphere-widget_003.png
        :alt: g sphere widget
        :srcset: /tutorial/08_widgets/images/sphx_glr_g_sphere-widget_003.png
        :class: sphx-glr-single-img
     


   .. tab-item:: Interactive Scene



       .. offlineviewer:: /home/runner/work/pyvista-tutorial/pyvista-tutorial/doc/source/tutorial/08_widgets/images/sphx_glr_g_sphere-widget_003.vtksz






.. GENERATED FROM PYTHON SOURCE LINES 165-168

And here is a screen capture of a user interacting with this

.. image:: ../../images/gifs/sphere-widget-c.gif

.. GENERATED FROM PYTHON SOURCE LINES 170-177

.. raw:: html

    <center>
      <a target="_blank" href="https://colab.research.google.com/github/pyvista/pyvista-tutorial/blob/gh-pages/notebooks/tutorial/08_widgets/g_sphere-widget.ipynb">
        <img src="https://colab.research.google.com/assets/colab-badge.svg" alt="Open In Colab"/ width="150px">
      </a>
    </center>


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

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


.. _sphx_glr_download_tutorial_08_widgets_g_sphere-widget.py:

.. only:: html

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

    .. container:: binder-badge

      .. image:: images/binder_badge_logo.svg
        :target: https://mybinder.org/v2/gh/pyvista/pyvista-tutorial/gh-pages?urlpath=lab/tree/notebooks/tutorial/08_widgets/g_sphere-widget.ipynb
        :alt: Launch binder
        :width: 150 px

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

      :download:`Download Jupyter notebook: g_sphere-widget.ipynb <g_sphere-widget.ipynb>`

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

      :download:`Download Python source code: g_sphere-widget.py <g_sphere-widget.py>`

    .. container:: sphx-glr-download sphx-glr-download-zip

      :download:`Download zipped: g_sphere-widget.zip <g_sphere-widget.zip>`


.. only:: html

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

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