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 plotting module #131

Closed
wants to merge 70 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
70 commits
Select commit Hold shift + click to select a range
5cf251a
Modify if-else statements in generators
Jun 11, 2018
7d456f1
Add DeprecationWarning to PlotEnvironment module
Jun 12, 2018
a39cdc7
Remove @property in history
Jun 12, 2018
464051e
Update test on optimizers
Jun 12, 2018
511286e
Mark environment tests as expected failures
Jun 12, 2018
1b370d0
Add plotters.py module
Jun 12, 2018
f44f451
Add formatters module
Jun 13, 2018
46110ec
Add tests for plotters module
Jun 12, 2018
2806abe
Fix bad behavior in discrete swarm generation
Jun 13, 2018
330fa3e
Add plotters.py module
Jun 12, 2018
bea0aeb
Add formatters module
Jun 13, 2018
aa51c7d
Add tests for plotters module
Jun 12, 2018
83342a9
Fix bad behavior in discrete swarm generation
Jun 13, 2018
79e8fa4
Add plotters to docs index (#130)
Jun 13, 2018
80f3383
Update docstrings in plotters.py (#130)
Jun 14, 2018
4bc9180
Add demo and documentation for plotters
Jun 14, 2018
cb8e37c
Update README.md with new plotting module
Jun 14, 2018
1d9a27a
Merge branch 'add-plotters-module' into add-plotters-to-docs
Jun 14, 2018
66944c1
Merge pull request #133 from ljvmiranda921/add-plotters-to-docs
Jun 14, 2018
4e900d1
Add Topology module
May 24, 2018
4489536
Add base Topology class
May 24, 2018
fe83760
Add Star class topology
May 24, 2018
215909c
Move functions to topologies
May 24, 2018
b47166b
Add Ring class Topology
Jun 6, 2018
aaa6f35
Rename methods in test_operators
Jun 6, 2018
f88025a
Update PSO implementations
Jun 6, 2018
58ae776
Add tests for topology module
Jun 6, 2018
fc9d0cd
Change init_pos to center
Jun 7, 2018
6a8a499
Add option to set init_pos
Jun 7, 2018
d8b68db
Add tests for init_pos
Jun 7, 2018
1803e6e
Rename "behavior" back into "options"
Jun 7, 2018
9bdef88
Add binary generators
Jun 7, 2018
f84d9c5
Add tests for generators
Jun 7, 2018
f04b27b
Expose init_pos in optimizers
Jun 7, 2018
4efd9e9
Use DiscreteSwarmOptimizer in init
Jun 7, 2018
8442304
Port base_discrete to backend
Jun 7, 2018
de88fed
Port BinaryPSO to backend
Jun 7, 2018
a8770e1
Fix test in test_binary
Jun 7, 2018
86e97f0
Use README.md instead of rst file
Jun 9, 2018
2df1039
Perform documentation cleanup for old docs
Jun 10, 2018
91d4fa8
Add documentation for backend (#121)
Jun 10, 2018
44abd3e
Add assets directory for images
Jun 10, 2018
e1a218d
Add TeX-related artifacts in .gitignore
Jun 10, 2018
9faa3de
Update docs on developer's guide (#121)
Jun 10, 2018
e626f74
Update default parameters in backend
Jun 10, 2018
f8f2d66
Update Jupyter Notebook examples (#121)
Jun 10, 2018
d6f22c7
Add use-case example for custom opts in RTD (#121)
Jun 10, 2018
dc10212
Update README.rst
ljvmiranda921 May 22, 2018
9a721c7
Update sphinx from 1.7.4 to 1.7.5
pyup-bot May 29, 2018
2070bce
Remove README.rst
Jun 10, 2018
ff58b03
Add branch matrix in README and docs
Jun 10, 2018
fc0070f
Bump version to 0.2.0
Jun 11, 2018
31c20d7
Update HISTORY.rst
Jun 11, 2018
a5e8c6f
Update setup.py classifiers
Jun 11, 2018
fc7e719
Modify if-else statements in generators
Jun 11, 2018
df1c957
Add DeprecationWarning to PlotEnvironment module
Jun 12, 2018
39ddf40
Remove @property in history
Jun 12, 2018
f8c6eb7
Update test on optimizers
Jun 12, 2018
3194383
Mark environment tests as expected failures
Jun 12, 2018
5ebe92d
Add plotters.py module
Jun 12, 2018
1f6ec18
Add formatters module
Jun 13, 2018
a56dac6
Add tests for plotters module
Jun 12, 2018
c65ab51
Fix bad behavior in discrete swarm generation
Jun 13, 2018
6f42ee7
Add plotters to docs index (#130)
Jun 13, 2018
862705c
Update docstrings in plotters.py (#130)
Jun 14, 2018
04949d0
Add demo and documentation for plotters
Jun 14, 2018
22d222e
Update README.md with new plotting module
Jun 14, 2018
f036052
Merge branch 'add-plotters-module'
Jun 14, 2018
258656b
Merge branch 'development' into add-plotters-module
Jun 14, 2018
8fe50a9
Merge github branch
Jun 14, 2018
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
7 changes: 4 additions & 3 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.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:
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