Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions docs/examples/heatmap-slicer.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ Compare Slices of 2D Arrays
===========================

.. note::
Unfortunately the interactive plots won't work on a website as there is no Python kernel
running. So all the interactive outputs have been replaced by gifs of what you should expect.
Unfortunately the interactive plots do not work on a website because there is no Python kernel
running. All of the interactive outputs have therefore been replaced by gifs of what you should expect.

The :meth:`~mpl_interactions.heatmap_slicer` function allow you to compare horizontal and/or vertical
slices of an arbitrary number of 2D arrays with just your mouse.
slices of an arbitrary number of 2D arrays using just your mouse.

.. code-block:: python

Expand All @@ -28,14 +28,14 @@ Options

The ``interaction_type`` argument controls how the plot updates. You can either use
``'move'`` in which case all mouse movements will be tracked, or you can use ``'click'``
and then the plot will only update when you click on one the arrays.
and the plot will only update when you click on one of the arrays.

The ``slices`` argument controls which slices to compare. It accepts values of ``'vertical'``, ``'horizontal'`` and ``'both'``
The ``slices`` argument controls which slices to compare. It accepts values of ``'vertical'``, ``'horizontal'``, and ``'both'``.

Potential Improvements
Potential improvements
^^^^^^^^^^^^^^^^^^^^^^

Do you wish the heatmap_slicer was better or worked with arbitrary angles? Then you should consider helping out
Do you wish the ``heatmap_slicer`` was better or worked with arbitrary angles? Then you should consider helping out
on one of the open issues for improving it!

1. `Improve the slices argument <https://github.com/ianhi/mpl-interactions/issues/57>`_
Expand Down
27 changes: 15 additions & 12 deletions docs/examples/image-segmentation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@
Image Segmentation
==================

Hopefully you won't often be faced with the task of manually segmenting images. However, for the times when you must
Hopefully you won't often be faced with the task of manually segmenting images. However, for the times when you must,
it's nice to not need to leave the comfort of python for some other program. Thus we arrive at the :class:`~mpl_interactions.image_segmenter` class.

(Credit where it's due: This tool was developed as part of a final project in Pavlos Protopapas' class `AC295 <https://harvard-iacs.github.io/2020-AC295/>`_, you can read more about it
in the project's final write up on `towards data science <https://towardsdatascience.com/how-we-built-an-easy-to-use-image-segmentation-tool-with-transfer-learning-546efb6ae98>`_)
(Credit where it's due: This tool was developed as part of a final project in Pavlos Protopapas' class `AC295 <https://harvard-iacs.github.io/2020-AC295/>`_ and you can read more about it
in the project's final write up on `towards data science <https://towardsdatascience.com/how-we-built-an-easy-to-use-image-segmentation-tool-with-transfer-learning-546efb6ae98>`_.)


.. code-block:: python
Expand All @@ -23,22 +23,25 @@ in the project's final write up on `towards data science <https://towardsdatasci
# If you don't keep a reference to the object the call backs will fail
segmenter = image_segmenter(image, nclasses = 3, mask_colors='red', mask_alpha=.76, figsize=(7,7))

# if working in a jupyter notebook
# If working in a Jupyter Notebook
display(segmenter)

This will create a matplotlib figure with the image in it. It will automatically apply
:meth:`~mpl_interactions.zoom_factory` and :meth:`~mpl_interactions.panhandler` so you can scroll to
zoom and use middle click to pan. If you left click and drag you can start creating the mask over the image.
This will create an image in a Matplotlib figure. It will automatically apply
:meth:`~mpl_interactions.zoom_factory` and :meth:`~mpl_interactions.panhandler`, so now you can:

* Scroll to zoom
* Use middle click to pan
* Left click and drag to start creating the mask over the image

.. image:: ../_static/segment.gif

You can switch which class you are marking by directly modifying the `segmenter`'s `current_class` variable.
You can switch which class you are marking by directly modifying the ``segmenter``'s ``current_class`` variable:

.. code-block:: python

segmenter.current_class = 2

and you can always directly the 2D mask with:
And you can always direct the 2D mask with:

.. code-block:: python

Expand All @@ -49,9 +52,9 @@ and you can always directly the 2D mask with:
Loading existing masks
----------------------

You can also load an existing mask. You will need to ensure that it does not contain values greater
than nclasses and that it has the same shape as the image. There are currently no safegaurds for
this and when there are exceptions in a matplotlib callback they can be hard to see in the notebook - so be careful!
You can also load an existing mask. You only need to ensure that (1) it does not contain values greater
than nclasses, and (2) that it has the same shape as the image. There are currently no safegaurds for
this, and when there are exceptions in a Matplotlib callback they can be hard to see in the notebook - so be careful!

.. code-block:: python

Expand Down
31 changes: 15 additions & 16 deletions docs/examples/mpl-sliders.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,26 +6,23 @@ Using Matplotlib Widgets
When using Matplotlib widgets you need to make sure you always keep a reference to the control sliders, otherwise the callbacks
will be garbage collected and cease to work.

This page is dedicated to showing how to use the ``interactive_*`` functions such as ``interactive_plot`` with Matplotlib widgets. For
a more general discussion of how to use the ``pyplot`` submodule see the :doc:`pyplot-notebook` page.
This page is dedicated to showing how to use the ``interactive_*`` functions---such as ``interactive_plot``---with Matplotlib widgets. For
a more general discussion of how to use the ``pyplot`` submodule see the :doc:`pyplot-notebooks` page.


Differences from ipywidgets sliders
-----------------------------------
**1.**

mpl-sliders are different form ipywidgets sliders in that they will only take a min and and max with
an optional step. Whereas for ipywidgets sliders you need to specify all the values (at least until version 8).
**1.** mpl-sliders are different from ipywidgets sliders in that they will only take a min and and max with
an optional step, while for ipywidgets sliders you need to specify all values (at least until version 8).
A consequence of this is that the various ``interactive_*`` methods will only use the first two values of any tuples
passed as a parameter (i.e. they will ignore the ``num`` argument to linspace).

**2.**

Laying out Matplotlib widgets is signifcantly more difficult than laying out elements in a webbrowser. So if you
pass an existing matplotlib widget a parameter it will update the plot as expected. However the ``interactive_*``
methods will not display it for you. In contrast when using ipywidgets widgets if you give a widget as a parameter
**2.** Laying out Matplotlib widgets is signifcantly more difficult than laying out elements in a web browser. If you
pass an existing Matplotlib widget a parameter then the plot will update as expected; however, the ``interactive_*``
methods will *not* display it for you. Alternatively, when using ipywidgets widgets, if you give a widget as a parameter
it will be included in the display of the controls created by the function.

Basic Example
Basic example
-------------

If you are not using the ``ipympl`` backend then ``mpl_interactions`` will automatically create a new figure to hold all the controls.
Expand All @@ -47,12 +44,14 @@ If you are not using the ``ipympl`` backend then ``mpl_interactions`` will autom

.. image:: interactive-plot-images/mpl-sliders.gif

Custom Positioning of Matplotlib Widgets
Custom positioning of Matplotlib widgets
----------------------------------------

There does not seem to be a consistent and simple way to layout Matplotlib widgets in the same figure as the plot that is to be controlled.
So current mpl_interactions will open a new figure to place all the controls in. If you would like the sliders and the plot to live in the same
figure then you will need to create your own Slider widget and use the :meth:`~mpl_interactions.interactive_plot_factory` function:
There does not seem to be a consistent and simple way to layout Matplotlib widgets in the same figure as the controlled plot.
To address this, mpl_interactions will open a new figure to place all the controls.

If you would like the sliders and the plot to live in the same figure, you will need to create your own Slider widget and use
the :meth:`~mpl_interactions.interactive_plot_factory` function:

.. code-block:: python

Expand Down
73 changes: 36 additions & 37 deletions docs/examples/pyplot-notebook.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,16 @@ Line plots

.. note::
Unfortunately the interactive plots won't work on a website as there is no Python kernel
running. So for all the interactive outputs have been replaced by gifs of what you should expect.
running. So for this site all the interactive outputs have been replaced by gifs of what you will see.

On this example page all of the outputs will use ipywidgets widgets for controls. However, if you are
not working in a Jupyter notebook then the examples here will still work with the built-in Matplolitb widgets.
For examples that that explicitly use matplotlib widgets instead of ipywidgets check out the :doc:`mpl-sliders` page.
On this example page all of the outputs will use **ipywidgets** widgets for controls. If you are
not working in a Jupyter Notebook the examples here will still work with the built-in Matplolitb widgets.
For examples that that explicitly use Matplotlib widgets instead of ipywidgets see the :doc:`mpl-sliders` page.


.. jupyter-execute::

# only run these lines if you are using a jupyter notebook or jupyter lab
# only run these lines if you are using a Jupyter Notebook or JupyterLab
%matplotlib ipympl
import ipywidgets as widgets

Expand All @@ -23,11 +23,11 @@ For examples that that explicitly use matplotlib widgets instead of ipywidgets c
from mpl_interactions import interactive_plot, interactive_plot_factory


Simple Example
Simple example
--------------

To use the interactive plot function all you need to do is write a function that will
return a numpy array or a list of numbers. You can provide the parameters that you want
To use the interactive plot function, write a function that will
return a NumPy array or a list of numbers. You can provide the parameters you want
to vary with sliders as keyword arguments to the :meth:`~mpl_interactions.interactive_plot` function.


Expand All @@ -39,7 +39,7 @@ to vary with sliders as keyword arguments to the :meth:`~mpl_interactions.intera
def f(x, tau, beta):
return np.sin(x*tau)*x**beta

and then to display the plot
Then to display the plot:

.. code-block:: python

Expand All @@ -51,24 +51,25 @@ and then to display the plot
Other ways to set parameter values
----------------------------------

You can set parameters with any of the following:
You can set parameters using any of the following:

- **numpy array/list** - Creates a slider with the values in the array
- **tuple** - Acts as an argument to linspace. Can have either 2 or 3 items
- **NumPy array/list** - Creates a slider with the values in the array
- **tuple** - Acts as an argument to linspace (can have either 2 or 3 items)
- **set** - Creates a categorical selector (order will not preserved)
- **set(tuple())** - Categorical selector with order maintained
- **scalar** - Fixed value
- **ipywidgets.Widget** any subclass of ``ipywidgets.Widget`` that has a ``value`` attribute can be used
- **matplotlib.widgets.Slider** or **RadioButton** - Note this cannot be used at the same time as an ipywidgets.Widget
- **ipywidgets.Widget** - any subclass of ``ipywidgets.Widget`` that has a ``value`` attribute can be used
- **matplotlib.widgets.Slider** or **RadioButton** - Note this cannot be used at the same time as an ``ipywidgets.Widget``

Here is an example using all of the possibilities with a dummy function. The ``display=False``
prevent the widgets from being automatically displayed which makes it easier to render them in this webpage,
but in general you should not need to use that.
Here is an example using all of the possibilities with a dummy function.


.. note::
The slider labels will not update here as that update requires a Python kernel.

Also, ``display=False`` prevents the widgets from being automatically displayed, making it easier to render
them on this webpage. In general you should not need to use it.

.. jupyter-execute::

def foo(x, **kwargs):
Expand All @@ -82,12 +83,12 @@ but in general you should not need to use that.
f = widgets.Checkbox(value=True, description='A checkbox!!')
display(interactive_plot(foo, x=x, a=a, b=b, c=c, d=d, e=e, f_=f, display=False)[-1])

Multiple Functions
Multiple functions
------------------

To plot multiple functions simply pass a list of functions as the first argument ``interactive_plot([f1, f2],...)``.
Also, whenever you add a legend to the resulting plot the names of the functions will be used as the labels, unless you
override that using the :ref:`plot_kwargs <plot-kwargs-section>` argument.
When you add a legend to the resulting plot, the function names will be used as the labels unless overriden
using the :ref:`plot_kwargs <plot-kwargs-section>` argument.

.. code-block:: python

Expand All @@ -102,18 +103,18 @@ override that using the :ref:`plot_kwargs <plot-kwargs-section>` argument.

Styling
-------
Calling ``interactive_plot`` will create and display a new figure for you. After that you can
use standard ``pyplot`` command to continue to modify the plot or you can use the references to the ``figure`` and ``axis``
that are returned by interactive_plot. Though be careful, anything you add will not be affected by the sliders.
Calling ``interactive_plot`` will create and display a new figure. Then you can either
use the standard ``pyplot`` command to continue modifying the plot, or you can use the references to the ``figure`` and ``axis``
that are returned by ``interactive_plot``. Though be careful, anything you add will not be affected by the sliders.



Slider Precision
Slider precision
^^^^^^^^^^^^^^^^

You can change the precision of individual slider displays by passing slider_format_string as a dictionary.
The below example will give the tau slider 99 decimal points of precision and use scientific notation to display it. The
beta slider will use the default 1 decimal point of precision
You can change the precision of individual slider displays by passing ``slider_format_string`` as a dictionary.
The example below gives the tau slider 99 decimal points of precision and uses scientific notation to display it. The
beta slider uses the default 1 decimal point of precision.

.. code-block:: python

Expand All @@ -126,26 +127,24 @@ Axis limits
You can control how the ``xlim/ylim`` behaves using the ``xlim/ylim`` arguments.
The options are:

1. ``'stretch'`` - The default, allow the x/y axes to expand but never shrink
2. ``'auto'`` - autoscale the limits for every plot update
3. ``'fixed'`` - never automatically update the limits
1. ``'stretch'`` - The default; allows the x/y axes to expand but never shrink
2. ``'auto'`` - Autoscales the limits for every plot update
3. ``'fixed'`` - Never automatically update the limits
4. [``float``, ``float``] - This value will be passed through to ``plt.xlim`` or ``plt.ylim``

Reference parameter values in the Title
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
You can make the title auto update with information about the values by using ``title`` argument.
Just use the name of one of the parameters as in a format specifier in the string.
e.g. to put the value of `tau` in the title and round it to two decimals use the following
title string: ``{'tau:.2f}'``
You can make the Title automatically update with information about the values by using ``title`` argument.
Use the name of one of the parameters as a format specifier in the string. For example use the following title string
to put the value of `tau` in the title and round it to two decimalsg: ``{'tau:.2f}'``

.. _plot-kwargs-section:

Matplolitb keyword arguments
^^^^^^^^^^^^^^^^^^^^^^^^^^^^

You can pass keyword arguments (kwargs) through to the ``plt.plot`` calls using the ``plot_kwargs``
argument to ``interactive_plot``. For example to add a label and some styling to one of the functions you
can do the following:
You can pass keyword arguments (*kwargs*) through to the ``plt.plot`` calls using the ``plot_kwargs``
argument to ``interactive_plot``. For example, to add a label and some styling to one of the functions try the following:

.. code-block:: python

Expand Down