Visualize relations of experimental data series by means of interactive plots in Python. With ...
Loo py Plot ... you can describe your problem in a plain python function
Loop yPlot ... you can run nested parameter sweeps with data dependencies
Loopy Plot ... you can explore the results by interactive plots (many thanks to matplotlib)
Loopy Plot ... you just configure what you want and everything else is done in the background for you
UPDATE: In the new-backend
branch a new backend based on expression graphs is developed. This approach will lead to a cleaner code base and a easier and more flexible user interface.
In the field of engineering science one common experiment task is to explore the behavior of a black-box under different inputs. The black-box can be a pure mathematical function, a numerical algorithm, the results of a complex simulation or even an experimental measurement. In many cases the input variation are done by nested for-loops.
While a nested for-loop iteration is simple to code the data management can be become quite complicated. This is even true when you want
- to quickly change the loop configuration (nested loops vs. zipped loops)
- to define data dependencies between different experiments
- to have an error recovery of the loop state because each iteration step takes a reasonable amount of time
- to plot multiple curves preserving the relations among each other
- to have a live-update of all plots while running the loop iteration
- to save experiment data in a readable and consistent way
- to reload the interactive plots later from an already finished experiment
- to write readable code which can be shared for collaboration
Especially the last point requires you to split the specific part of an experiment from its administration (all the seven point above). A very natural way of splitting is to use a function. Everything inside the function describes the specific experiment. The function arguments and return values are used for the administration of the experiment. In this sense LoopyPlot is a dependency injection (DI) container for looped functions with the capability of creating interactive plots.
The following demo shows the basic features of LoopyPlot:
- Configure the function arguments with loops
- Run the nested loops
- Plot the function return values and show the data cursor
Further information can be found in the which is more detailed.
We will show the basis features by means of the nice lissajous example. First of all we need to write the experiment as a python function. Here we use two sinusoidal functions in order to create the lissajous curves at the end.
from numpy import pi, cos, sin
def lissajous(t: 's', freq: 'Hz', phi=0):
xpos: 'cm' = cos(2*pi*freq * t + phi)
ypos: 'cm' = sin(2*pi * t)
return xpos, ypos
In addition to the plain definition of the sinusoidal functions we can optionally specify the units of the variables. These unit annotations are possible thanks the new syntax for variable annotations in python 3.6 and used later for plotting.
In order to explore the behavior of your lissajous function we
sweep the argument t
and phi
.
import loopyplot
# (1) create task object from lissajous function and configure the loops
lissajous = loopyplot.Task(lissajous)
lissajous.args.freq.value = 2
lissajous.args.t.sweep(0, 1, num=30)
lissajous.args.phi.iterate(pi/4, pi/2, 3*pi/4)
Afterwards we can run the nested double sweep and plot the results.
# (2) run the the configured lissajous task
lissajous.run()
# (3) display the results
lissajous.plot('t', 'xpos')
lissajous.plot('t', 'ypos', row=1, accumulate=[])
lissajous.plot('xpos', 'ypos', row=[0, 1], col=1, squeeze='t', accumulate=[])
The matplotlib figure has an interactive data cursor. You can click at any point (e.g. in the upper left right axes) in order to update the data cursor and explore the relations between the plots.
Currently, LoopyPlot is ...
- a prototype implementation of the seven features listed above, and is
- in alpha stage looking for user feedback
in order to reach the vision of coding your experiments in a readable and reuseable manner. Since LoopyPlot mainly focuses on experimental measurements speed is not an issue for development right now.
Open issues before first beta release 0.1:
- improve logging
- refactoring the dependency management
- add binary sweep
- docstings
- write more tests
- write more use case demos
- csv: save arrays in an extra csv file (instead of string encoding)
Further ideas (beyond 0.1):
- implement horizontal nested task lists over vertical looped lists
LoopyPlot is developed under python 3.6
(older versions can be used but are not tested)
and intended to use with an ipython shell ipython --pylab
(version 5.6.0 is used for development).
In order instal LoopyPlot, simply download the repository, change into
the folder LoopyPlot
and
pip install . --user
If necessary this will automatically install the dependencies:
- matplotlib
- numpy
- pandas (for pretty print of the value tables)
- pydot (for drawing the depedency graph)
LoopyPlot is licenced under GPL 3.