Skip to content

Commit

Permalink
removed pyparsing dependency and moved plotting into separate file
Browse files Browse the repository at this point in the history
  • Loading branch information
bad-ants-fleet committed Nov 10, 2020
1 parent 2d2ee7c commit 097ed24
Show file tree
Hide file tree
Showing 9 changed files with 197 additions and 163 deletions.
18 changes: 11 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,13 +117,17 @@ Then go ahead and execute `ozzy.py`:
```

## Version
v0.9 -- code cleanup
* removed networkx dependency
* moved plotting libraries and functions into a separate file to avoid automatic import.

v0.8 -- beta status
* now using logging
* python >= 3.7 only
* improved header documentation
* using entry_points for crnsimulator script
* set defaultrate = 1 (new postprocessing strandard)
* new commandline arguments: labels, labels-strict
* support the constant concentration flag
* now using logging
* python >= 3.7 only
* improved header documentation
* using entry_points for crnsimulator script
* set defaultrate = 1 (new postprocessing strandard)
* new commandline arguments: labels, labels-strict
* support the constant concentration flag

[oscillator.crn]: <https://github.com/bad-ants-fleet/crnsimulator/blob/master/tests/crns/oscillator.crn>
5 changes: 2 additions & 3 deletions crnsimulator/__init__.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
"""
Simulate formal Chemical Reaction Networks using ODEs (library interface).
Simulate formal chemical reaction networks using ODEs (library interface).
"""

__version__ = "v0.8"
__version__ = "v0.9"

import logging
logging.getLogger(__name__).addHandler(logging.NullHandler())

from crnsimulator.crn_parser import parse_crn_string, parse_crn_file
from crnsimulator.reactiongraph import ReactionGraph
from crnsimulator.solver import writeODElib, get_integrator
from crnsimulator.odelib_template import ode_plotter
5 changes: 2 additions & 3 deletions crnsimulator/crn_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,10 @@
Test using tests/test_crn_parser.py.
"""

from pyparsing import (Word, Literal, Group, Suppress, Combine, Optional,
from pyparsing import (Word, Literal, Group, Suppress, Combine, Optional, ParseException,
alphas, nums, alphanums, delimitedList, StringStart, StringEnd, LineEnd,
ZeroOrMore, OneOrMore, pythonStyleComment, ParseElementEnhance)

from pyparsing import ParseException

class CRNParseError(Exception):
pass

Expand Down Expand Up @@ -203,3 +201,4 @@ def parse_crn_string(data, process = True, **kwargs):
else:
return crn_document.parseString(data).asList()


99 changes: 7 additions & 92 deletions crnsimulator/odelib_template.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
#!/usr/bin/env python3
#!/usr/bin/env python
"""
A template file to simulate a specific system of Ordinary Differential Equations (ODEs).
... or an autogenerated script from the *crnsimulator* Python package.
Note: If this file is executable, it is *autogenerated*.
This means it contains a system of hardcoded ODEs together with some
default parameters. It may be helfpul to teak e.g. the ode_plotter
function, but beware that this file may be overwritten by the next
execution of the `crnsimulator` executable.
For heavy edits, is recommended to edit the source directly at:
"crnsimulator.odelib_template" or provide your own template file.
Alternatively, use the option --output to prevent the loss of your edits.
default parameters. While it may be tempting to tweak some functions,
beware that this file may be overwritten by the next execution of the
`crnsimulator` executable. Edits should be done at the source file:
"crnsimulator.odelib_template.py" or you can provide an alternative
template file. Use the option --output to avoid overwriting this file.
Usage:
python #<&>FILENAME<&># --help
Expand All @@ -22,96 +21,11 @@

import argparse
import numpy as np
import matplotlib.pyplot as plt
from scipy.integrate import odeint

import seaborn as sns
sns.set(style="darkgrid", font_scale=1, rc={"lines.linewidth": 2.0})

class ODETemplateError(Exception):
pass


def ode_plotter(name, t, ny, svars, log = False, labels = None,
xlim = None, ylim = None, plim = None, labels_strict = False):
""" Plots the ODE trajectories.
Args:
name (str): Name of the outputfile including extension (e.g. *.pdf)
t (list[flt]) : time units plotted on the x-axis.
ny (list[list[flt]]) : a list of trajectories plotted on the y-axis.
svars (list[str]): A list of names for every trajectory in ny
log (bool,optional): Plot data on a logarithmic time scale
labels (set(),optional): Define species that appear labelled in the plot
xlim ((float,float), optional): matplotlib xlim.
ylim ((float,float), optional): matplotlib ylim.
plim (float, optional): Minimal occupancy to plot a trajectory. Defaults to None.
labels_strict (bool, optional): Only print labels that were specified using labels.
Prints:
A file containing the plot (Format *.pdf, *.png, etc.)
Returns:
[str]: Name of the file containing the plot
"""
fig, ax = plt.subplots(1, 1, figsize=(8, 4.5))

# b : blue.
# g : green.
# r : red.
# c : cyan.
# m : magenta.
# y : yellow.
# k : black.
mycolors = ['blue',
'red',
'green',
'orange',
'maroon',
'springgreen',
'cyan',
'magenta',
'yellow']
mycolors += list('kkkkkkkkkkk')

if labels:
i = 0
for e, y in enumerate(ny):
if svars[e] in labels:
ax.plot(t, y, '-', label=svars[e], color=mycolors[i])
i = i + 1 if i < len(mycolors) - 1 else 0
elif not labels_strict:
ax.plot(t, y, '--', lw=0.1, color='gray', zorder=1)
else:
for e, y in enumerate(ny):
if plim is None or max(y) > plim:
ax.plot(t, y, '-', label=svars[e])
else:
ax.plot(t, y, '--', lw=0.1, color='gray', zorder=1)

plt.title(name)
if xlim:
plt.xlim(xlim)
# plt.xticks(np.arange(0, 61, step=20))

if ylim:
plt.ylim(ylim)
# plt.yticks(np.arange(0, 51, step=10))

ax.set_xlabel('Time', fontsize=16)
ax.set_ylabel('Concentration', fontsize=16)
if log:
ax.set_xscale('log')
else:
ax.set_xscale('linear')

plt.legend(loc='upper right')
fig.tight_layout()
plt.savefig(name)
plt.close()
return name


rates = {
#<&>RATES<&>#
}
Expand Down Expand Up @@ -289,6 +203,7 @@ def integrate(args, setlogger = False):
print(' '.join(map("{:.9e}".format, i)))

if args.pyplot:
from crnsimulator.plotting import ode_plotter
plotfile = ode_plotter(args.pyplot, time, ny, svars,
log=True if args.t_log else False,
labels=set(args.labels),
Expand Down
84 changes: 84 additions & 0 deletions crnsimulator/plotting.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@

import matplotlib.pyplot as plt
import seaborn as sns
sns.set(style="darkgrid", font_scale=1, rc={"lines.linewidth": 2.0})

def ode_plotter(name, t, ny, svars, log = False, labels = None,
xlim = None, ylim = None, plim = None, labels_strict = False):
""" Plots the ODE trajectories.
Args:
name (str): Name of the outputfile including extension (e.g. *.pdf)
t (list[flt]) : time units plotted on the x-axis.
ny (list[list[flt]]) : a list of trajectories plotted on the y-axis.
svars (list[str]): A list of names for every trajectory in ny
log (bool,optional): Plot data on a logarithmic time scale
labels (set(),optional): Define species that appear labelled in the plot
xlim ((float,float), optional): matplotlib xlim.
ylim ((float,float), optional): matplotlib ylim.
plim (float, optional): Minimal occupancy to plot a trajectory. Defaults to None.
labels_strict (bool, optional): Only print labels that were specified using labels.
Prints:
A file containing the plot (Format *.pdf, *.png, etc.)
Returns:
[str]: Name of the file containing the plot
"""
fig, ax = plt.subplots(1, 1, figsize=(8, 4.5))

# b : blue.
# g : green.
# r : red.
# c : cyan.
# m : magenta.
# y : yellow.
# k : black.
mycolors = ['blue',
'red',
'green',
'orange',
'maroon',
'springgreen',
'cyan',
'magenta',
'yellow']
mycolors += list('kkkkkkkkkkk')

if labels:
i = 0
for e, y in enumerate(ny):
if svars[e] in labels:
ax.plot(t, y, '-', label=svars[e], color=mycolors[i])
i = i + 1 if i < len(mycolors) - 1 else 0
elif not labels_strict:
ax.plot(t, y, '--', lw=0.1, color='gray', zorder=1)
else:
for e, y in enumerate(ny):
if plim is None or max(y) > plim:
ax.plot(t, y, '-', label=svars[e])
else:
ax.plot(t, y, '--', lw=0.1, color='gray', zorder=1)

plt.title(name)
if xlim:
plt.xlim(xlim)
# plt.xticks(np.arange(0, 61, step=20))

if ylim:
plt.ylim(ylim)
# plt.yticks(np.arange(0, 51, step=10))

ax.set_xlabel('Time', fontsize=16)
ax.set_ylabel('Concentration', fontsize=16)
if log:
ax.set_xscale('log')
else:
ax.set_xscale('linear')

plt.legend(loc='upper right')
fig.tight_layout()
plt.savefig(name)
plt.close()
return name

0 comments on commit 097ed24

Please sign in to comment.