Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add plotters module #135

Merged
merged 13 commits into from
Jun 14, 2018
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
39 changes: 30 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -186,27 +186,48 @@ fresh run to plot the cost and create animation.
```python
import pyswarms as ps
from pyswarms.utils.functions import single_obj as fx
from pyswarms.utils.environments import PlotEnvironment
from pyswarms.utils.plotters import plot_cost_history
# Set-up optimizer
options = {'c1':0.5, 'c2':0.3, 'w':0.9}
optimizer = ps.single.GlobalBestPSO(n_particles=10, dimensions=3, options=options)
# Initialize plot environment
plt_env = PlotEnvironment(optimizer, fx.sphere_func, 1000)
optimizer = ps.single.GlobalBestPSO(n_particles=50, dimensions=2, options=options)
optimizer.optimize(fx.sphere_func, iters=100)
# Plot the cost
plt_env.plot_cost(figsize=(8,6));
plot_cost_history(optimizer.cost_history)
plt.show()
```

<img src="./docs/examples/output_9_0.png" width="460">
<img src="./docs/examples/output_8_0.png" width="460">

We can also plot the animation,
We can also plot the animation...

```python
plt_env.plot_particles2D(limits=((-1.2,1.2),(-1.2,1.2))
from pyswarms.utils.plotters.formatters import Mesher
from pyswarms.utils.plotters.formatters import Designer
# Plot the sphere function's mesh for better plots
m = Mesher(func=fx.sphere_func)
# Adjust figure limits
d = Designer(limits=[(-1,1), (-1,1), (-0.1,1)],
label=['x-axis', 'y-axis', 'z-axis'])
```

<img src="./docs/examples/output_3d.gif" width="460">
In 2D,

```python
plot_contour(pos_history=optimizer.pos_history, mesher=m, mark=(0,0))
```

![Contour](https://i.imgur.com/H3YofJ6.gif)

Or in 3D!

```python
pos_history_3d = m.compute_history_3d(optimizer.pos_history) # preprocessing
animation3d = plot_surface(pos_history=pos_history_3d,
mesher=m, designer=d,
mark=(0,0,0))
```

![Surface](https://i.imgur.com/kRb61Hx.gif)

## Contributing

Expand Down
9 changes: 5 additions & 4 deletions docs/api/_pyswarms.utils.rst
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
Utilities
=========

This includes various utilities to help in optimization. In the future,
parameter search and plotting techniques will be incoroporated in this
module.
This includes various utilities to help in optimization. Some utilities
include benchmark objective functions, hyperparameter search, and plotting
functionalities.

.. toctree::

pyswarms.utils.functions
pyswarms.utils.search
pyswarms.utils.environments
pyswarms.utils.plotters
pyswarms.utils.environments
4 changes: 4 additions & 0 deletions docs/api/pyswarms.utils.environments.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ pyswarms.utils.environments package

.. automodule:: pyswarms.utils.environments

.. deprecated:: 0.2.1
This module will be deprecated in the next release. Please use
:mod:`pyswarms.utils.plotters` instead.

pyswarms.utils.environments.plot_environment module
----------------------------------------------------

Expand Down
20 changes: 20 additions & 0 deletions docs/api/pyswarms.utils.plotters.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
pyswarms.utils.plotters package
================================

.. automodule:: pyswarms.utils.plotters

pyswarms.utils.plotters.plotters module
----------------------------------------

.. automodule:: pyswarms.utils.plotters.plotters
:members:
:undoc-members:
:show-inheritance:

pyswarms.utils.plotters.formatters module
------------------------------------------

.. automodule:: pyswarms.utils.plotters.formatters
:members:
:undoc-members:
:show-inheritance:
2 changes: 2 additions & 0 deletions docs/assets/inheritance.aux
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
\relax
\gdef \sa@multi@numpages {0}
155 changes: 155 additions & 0 deletions docs/assets/inheritance.fdb_latexmk

Large diffs are not rendered by default.

250 changes: 250 additions & 0 deletions docs/assets/inheritance.fls

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions docs/assets/optimization_loop.aux
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
\relax
\gdef \sa@multi@numpages {0}
156 changes: 156 additions & 0 deletions docs/assets/optimization_loop.fdb_latexmk

Large diffs are not rendered by default.

248 changes: 248 additions & 0 deletions docs/assets/optimization_loop.fls

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions docs/assets/pyswarms_api.aux
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
\relax
\gdef \sa@multi@numpages {0}
128 changes: 128 additions & 0 deletions docs/assets/pyswarms_api.fdb_latexmk

Large diffs are not rendered by default.

204 changes: 204 additions & 0 deletions docs/assets/pyswarms_api.fls

Large diffs are not rendered by default.

Binary file added docs/examples/output_8_0.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed docs/examples/output_9_0.png
Binary file not shown.
155 changes: 110 additions & 45 deletions docs/examples/visualization.rst
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,29 @@ and Windows users, it can be installed via:

$ conda install -c conda-forge ffmpeg

First, we need to import the
``pyswarms.utils.environments.PlotEnvironment`` class. This enables us
to use various methods to create animations or plot costs.
.. code:: ipython3

import sys
# Change directory to access the pyswarms module
sys.path.append('../')

.. code:: ipython3

print('Running on Python version: {}'.format(sys.version))


.. code:: shell

Running on Python version: 3.6.3 |Anaconda custom (64-bit)| (default, Oct 13 2017, 12:02:49) [GCC 7.2.0]

.. code-block:: ipython

In this example, we will demonstrate three plotting methods available on
PySwarms: - ``plot_cost_history``: for plotting the cost history of a
swarm given a matrix - ``plot_contour``: for plotting swarm trajectories
of a 2D-swarm in two-dimensional space - ``plot_surface``: for plotting
swarm trajectories of a 2D-swarm in three-dimensional space

.. code:: ipython3

# Import modules
import matplotlib.pyplot as plt
Expand All @@ -31,7 +49,7 @@ to use various methods to create animations or plot costs.
# Import PySwarms
import pyswarms as ps
from pyswarms.utils.functions import single_obj as fx
from pyswarms.utils.environments import PlotEnvironment
from pyswarms.utils.plotters import (plot_cost_history, plot_contour, plot_surface)

# Some more magic so that the notebook will reload external python modules;
# see http://stackoverflow.com/questions/1907993/autoreload-of-modules-in-ipython
Expand All @@ -41,89 +59,136 @@ to use various methods to create animations or plot costs.
The first step is to create an optimizer. Here, we're going to use
Global-best PSO to find the minima of a sphere function. As usual, we
simply create an instance of its class ``pyswarms.single.GlobalBestPSO``
by passing the required parameters that we will use.
by passing the required parameters that we will use. Then, we'll call
the ``optimize()`` method for 100 iterations.

.. code-block:: ipython
.. code:: ipython3

options = {'c1':0.5, 'c2':0.3, 'w':0.9}
optimizer = ps.single.GlobalBestPSO(n_particles=10, dimensions=3, options=options)

Initializing the ``PlotEnvironment``
------------------------------------
optimizer = ps.single.GlobalBestPSO(n_particles=50, dimensions=2, options=options)
cost, pos = optimizer.optimize(fx.sphere_func, iters=100)

Think of the ``PlotEnvironment`` as a container in which various
plotting methods can be called. In order to create an instance of this
class, we need to pass the optimizer object, the objective function, and
the number of iterations needed. The ``PlotEnvironment`` will then
simulate these parameters so as to build the plots.

.. code-block:: ipython
.. parsed-literal::

plt_env = PlotEnvironment(optimizer, fx.sphere_func, 1000)
INFO:pyswarms.single.global_best:================================
Optimization finished!
Final cost: 0.0000
Best value: [0.00012738838189254011, -0.00011284635020703156]


Plotting the cost
-----------------

To plot the cost, we simply need to call the ``plot_cost()`` function.
There are pre-set defaults in this method already, but we can customize
by passing various arguments into it such as figure size, title, x- and
y-labels and etc. Furthermore, this method also accepts a keyword
argument ``**kwargs`` similar to ``matplotlib``. This enables us to
further customize various artists and elements in the plot.
Plotting the cost history
-------------------------

For now, let's stick with the default one. We'll just call the
``plot_cost()`` and ``show()`` it.
To plot the cost history, we simply obtain the ``cost_history`` from the
``optimizer`` class and pass it to the ``cost_history`` function.
Furthermore, this method also accepts a keyword argument ``**kwargs``
similar to ``matplotlib``. This enables us to further customize various
artists and elements in the plot. In addition, we can obtain the
following histories from the same class: - mean\_neighbor\_history:
average local best history of all neighbors throughout optimization -
mean\_pbest\_history: average personal best of the particles throughout
optimization

.. code-block:: ipython
.. code:: ipython3

plt_env.plot_cost(figsize=(8,6));
plot_cost_history(cost_history=optimizer.cost_history)
plt.show()



.. image:: output_9_0.png
.. image:: output_8_0.png


Animating swarms
----------------

The ``PlotEnvironment()`` offers two methods to perform animation,
``plot_particles2D()`` and ``plot_particles3D()``. As its name suggests,
these methods plot the particles in a 2-D or 3-D space. You can choose
which dimensions will be plotted using the ``index`` argument, but the
default takes the first 2 (or first three in 3D) indices of your swarm
dimension.
The ``plotters`` module offers two methods to perform animation,
``plot_contour()`` and ``plot_surface()``. As its name suggests, these
methods plot the particles in a 2-D or 3-D space.

Each animation method returns a ``matplotlib.animation.Animation`` class
that still needs to be animated by a ``Writer`` class (thus
necessitating the installation of a writer module). For the proceeding
examples, we will convert the animations into an HTML5 video. In such
case, we need to invoke some extra methods to do just that.

.. code-block:: ipython
.. code:: ipython3

# equivalent to rcParams['animation.html'] = 'html5'
# See http://louistiao.me/posts/notebooks/save-matplotlib-animations-as-gifs/
rc('animation', html='html5')

Lastly, it would be nice to add meshes in our swarm to plot the sphere
function. This enables us to visually recognize where the particles are
with respect to our objective function. We can accomplish that using the
``Mesher`` class.

.. code:: ipython3

from pyswarms.utils.plotters.formatters import Mesher

.. code:: ipython3

# Initialize mesher with sphere function
m = Mesher(func=fx.sphere_func)

There are different formatters available in the
``pyswarms.utils.plotters.formatters`` module to customize your plots
and visualizations. Aside from ``Mesher``, there is a ``Designer`` class
for customizing font sizes, figure sizes, etc. and an ``Animator`` class
to set delays and repeats during animation.

Plotting in 2-D space
~~~~~~~~~~~~~~~~~~~~~

.. code-block:: ipython
We can obtain the swarm's position history using the ``pos_history``
attribute from the ``optimizer`` instance. To plot a 2D-contour, simply
pass this together with the ``Mesher`` to the ``plot_contour()``
function. In addition, we can also mark the global minima of the sphere
function, ``(0,0)``, to visualize the swarm's "target".

HTML(plt_env.plot_particles2D(limits=((-1.2,1.2),(-1.2,1.2))).to_html5_video())
.. code:: ipython3

.. image:: output_2d.gif
# Make animation
animation = plot_contour(pos_history=optimizer.pos_history,
mesher=m,
mark=(0,0))

# Enables us to view it in a Jupyter notebook
HTML(animation.to_html5_video())

.. image:: https://i.imgur.com/g7UcOgU.gif


Plotting in 3-D space
~~~~~~~~~~~~~~~~~~~~~

To plot in 3D space, we need a position-fitness matrix with shape
``(iterations, n_particles, 3)``. The first two columns indicate the x-y
position of the particles, while the third column is the fitness of that
given position. You need to set this up on your own, but we have
provided a helper function to compute this automatically

.. code:: ipython3

# Obtain a position-fitness matrix using the Mesher.compute_history_3d()
# method. It requires a cost history obtainable from the optimizer class
pos_history_3d = m.compute_history_3d(optimizer.pos_history)

.. code:: ipython3

HTML(plt_env.plot_particles3D(limits=((-1.2,1.2),(-1.2,1.2),(-1.2,1.2))).to_html5_video())
# Make a designer and set the x,y,z limits to (-1,1), (-1,1) and (-0.1,1) respectively
from pyswarms.utils.plotters.formatters import Designer
d = Designer(limits=[(-1,1), (-1,1), (-0.1,1)], label=['x-axis', 'y-axis', 'z-axis'])

.. code:: ipython3

.. image:: output_3d.gif
# Make animation
animation3d = plot_surface(pos_history=pos_history_3d, # Use the cost_history we computed
mesher=m, designer=d, # Customizations
mark=(0,0,0)) # Mark minima

# Enables us to view it in a Jupyter notebook
HTML(animation3d.to_html5_video())

.. image:: https://i.imgur.com/IhbKTIE.gif
Loading