Source code for cbmpy.CBPlot

"""
CBMPy: CBPlot module
====================
PySCeS Constraint Based Modelling (http://cbmpy.sourceforge.net)
Copyright (C) 2009-2017 Brett G. Olivier, VU University Amsterdam, Amsterdam, The Netherlands

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>

Author: Brett G. Olivier
Contact email: bgoli@users.sourceforge.net
Last edit: $Author: bgoli $ ($Id: CBPlot.py 575 2017-04-13 12:18:44Z bgoli $)

"""

# preparing for Python 3 port
from __future__ import division, print_function
from __future__ import absolute_import
#from __future__ import unicode_literals

import os, time, gc
import numpy
from . import CBWrite, CBTools
from .CBConfig import __CBCONFIG__ as __CBCONFIG__
__DEBUG__ = __CBCONFIG__['DEBUG']
__version__ = __CBCONFIG__['VERSION']

_HAVE_MATPLOTLIB_ = True
try:
    import matplotlib
    import matplotlib.pyplot as pyplot
except ImportError:
    print('No Matplotlib available')
    matplotlib = None
    pyplot = None
    _HAVE_MATPLOTLIB_ = False

[docs]def plotFluxVariability(fva_data, fva_names, fname, work_dir=None, title=None, ySlice=None, minHeight=None, maxHeight=None, roundec=None, autoclose=True, fluxval=True, type='png'): """ Plots and saves as an image the flux variability results as generated by CBSolver.FluxVariabilityAnalysis. - *fva_data* FluxVariabilityAnalysis() FVA OUTPUT_ARRAY - *fva_names* FluxVariabilityAnalysis() FVA OUTPUT_NAMES - *fname* filename_base for the CSV output - *work_dir* [default=None] if set the output directory for the csv files - *title* [default=None] the user defined title for the graph - *ySlice* [default=None] this sets an absolute (fixed) limit on the Y-axis (+- ySlice) - *minHeight* [default=None] the minimum length that defined a span - *maxHeight* [default=None] the maximum length a span can obtain, bar will be limited to maxHeight and coloured yellow - *roundec* [default=None] an integer indicating at which decimal to round off output. Default is no rounding. - *autoclose* [default=True] autoclose plot after save - *fluxval* [default=True] plot the flux value - *type* [default='png'] the output format, depends on matplotlib backend e.g. 'png', 'pdf', 'eps' """ assert _HAVE_MATPLOTLIB_, "\nPlotting requires Matplotlib" l_cntr = 0 c_width = 0.8 g_bars = [] g_bars_lcorner =[] fba_val_lines =[] vResults = {} PLOTLOG = False outputNames = [] Ymagic = [] FIG = matplotlib.pyplot.figure(num=5, figsize=(16,9)) pyplot.hold(True) for r in range(fva_data.shape[0]): HASMIN = False HASMAX = False if roundec == None: fv_min = fva_data[r,2] fv_fba = fva_data[r,0] fv_max = fva_data[r,3] else: fv_min = round(fva_data[r,2], roundec) fv_fba = round(fva_data[r,0], roundec) fv_max = round(fva_data[r,3], roundec) if fv_fba != numpy.NaN: if fv_min != numpy.NaN: if fv_min < fv_fba: HASMIN = True if fv_max != numpy.NaN: if fv_max > fv_fba: HASMAX = True b_height = 0.0 b_height1 = 0.0 b_height2 = 0.0 if HASMAX: b_height1 = fv_max-fv_fba if HASMIN: b_height2 = fv_fba-fv_min b_height = abs(b_height1)+abs(b_height2) HCheckMin = False HCheckMax = False if minHeight == None: HCheckMin = True elif minHeight != None and b_height >= minHeight: HCheckMin = True if maxHeight == None: HCheckMax = True elif maxHeight != None and b_height <= maxHeight: HCheckMax = True if b_height > 0.0 and HCheckMin and HCheckMax: outputNames.append(fva_names[r]) if HASMIN: bottom = fv_min else: bottom = fv_fba Ymagic.append(bottom) Ymagic.append(bottom+b_height) ## print 'Bar = (%s,%s)' % (bottom, bottom+b_height) g_bars.append(matplotlib.pyplot.bar(left=l_cntr, height=b_height,\ width=c_width, bottom=bottom, log=PLOTLOG, hold=True)) if fluxval: fba_val_lines.append(matplotlib.pyplot.hlines(fv_fba, g_bars[-1][0].get_x(),\ g_bars[-1][0].get_x()+g_bars[-1][0].get_width(), colors='r', linestyles='solid', lw=2)) g_bars_lcorner.append(l_cntr) l_cntr += c_width vResults.update({fva_names[r] : fva_data[r].copy()}) elif b_height > 0.0 and HCheckMin: outputNames.append(fva_names[r]) if HASMIN: bottom = fv_min else: bottom = fv_fba if bottom < fv_fba - maxHeight: bottom = fv_fba- maxHeight if bottom + b_height > fv_fba + maxHeight: b_height = abs(fv_fba - bottom) + maxHeight Ymagic.append(bottom) Ymagic.append(bottom+b_height) ## print 'Bar = (%s,%s)' % (bottom, bottom+b_height) g_bars.append(matplotlib.pyplot.bar(left=l_cntr, height=b_height,\ width=c_width, bottom=bottom, log=PLOTLOG, hold=True, color='y', lw=0.5)) if fluxval: fba_val_lines.append(matplotlib.pyplot.hlines(fv_fba, g_bars[-1][0].get_x(),\ g_bars[-1][0].get_x()+g_bars[-1][0].get_width(), colors='r', linestyles='solid', lw=2)) g_bars_lcorner.append(l_cntr) l_cntr += c_width vResults.update({fva_names[r] : fva_data[r].copy()}) if __DEBUG__: print('len fva_names', len(fva_names)) if __DEBUG__: print('len g_bars', len(g_bars)) ## print 'fva_data.shape', fva_data.shape outputNames = [l.replace('_LPAREN_e_RPAREN_','_e') for l in outputNames] matplotlib.pyplot.xticks(numpy.array(g_bars_lcorner)+(c_width/2.0), outputNames,\ rotation='vertical', size='xx-small') if title == None: matplotlib.pyplot.title('%s has %i varying fluxes' % (fname, len(g_bars))) else: matplotlib.pyplot.title('%s' % (title)) matplotlib.pyplot.ylabel('Variability') if len(Ymagic) > 0: yhi = max(Ymagic) + 0.01*max(Ymagic) ylow = min(Ymagic) - abs(0.01*min(Ymagic)) if ySlice != None: yhi = abs(ySlice) ylow = -abs(ySlice) matplotlib.pyplot.ylim(ylow, yhi) if __DEBUG__: print('Plotting y %s --> %s' % (ylow, yhi)) if work_dir != None: fname = os.path.join(work_dir, fname) matplotlib.pyplot.savefig(fname+'.%s' % type) pyplot.hold(False) if autoclose: matplotlib.pyplot.close('all')