"""
hydraulics.postprocessing
~~~~~~~~~~~~~~~~~~~~~~
The module :mod:`hydraulics.postprocessing` defines post-processing to apply
on Turgor-Wheat outputs, and provides a front-end to automatize the generation of graphs
for validation of the outputs.
Please use front-ends :func:`postprocessing` and :func:`generate_graphs`.
"""
from __future__ import division # use "//" to do integer division
import os
import pandas as pd
import matplotlib.pyplot as plt
from openalea.cnwgrass.hydraulics import simulation as hydraulics_simulation
from openalea.cnwgrass.hydraulics import parameters as hydraulics_parameters
from openalea.cnwgrass.integration import tools as integration_tools
#: the time index
T_INDEX = hydraulics_simulation.Simulation.T_INDEX
#: the index to locate the plants in the modelled system
PLANTS_INDEXES = hydraulics_simulation.Simulation.PLANTS_INDEXES
#: concatenation of :attr:`T_INDEX` and :attr:`PLANTS_INDEXES`
PLANTS_T_INDEXES = hydraulics_simulation.Simulation.PLANTS_T_INDEXES
#: plants post-processing variables
PLANTS_POSTPROCESSING_VARIABLES = []
#: concatenation of :attr:`PLANTS_T_INDEXES`, :attr:`PLANTS_RUN_VARIABLES <hydraulics.simulation.Simulation.PLANTS_RUN_VARIABLES>` and :attr:`PLANTS_POSTPROCESSING_VARIABLES`
PLANTS_RUN_POSTPROCESSING_VARIABLES = set(PLANTS_T_INDEXES + hydraulics_simulation.Simulation.PLANTS_RUN_VARIABLES + PLANTS_POSTPROCESSING_VARIABLES)
#: the indexes to locate the axes in the modelled system
AXES_INDEXES = hydraulics_simulation.Simulation.AXES_INDEXES
#: concatenation of :attr:`T_INDEX` and :attr:`AXES_INDEXES`
AXES_T_INDEXES = hydraulics_simulation.Simulation.AXES_T_INDEXES
#: axes post-processing variables
AXES_POSTPROCESSING_VARIABLES = []
#: concatenation of :attr:`AXES_T_INDEXES`, :attr:`AXES_RUN_VARIABLES <cnmetabolism.simulation.Simulation.AXES_RUN_VARIABLES>` and :attr:`AXES_POSTPROCESSING_VARIABLES`
AXES_RUN_POSTPROCESSING_VARIABLES = set(AXES_T_INDEXES + hydraulics_simulation.Simulation.AXES_RUN_VARIABLES + AXES_POSTPROCESSING_VARIABLES)
#: the indexes to locate the phytomers in the modelled system
PHYTOMERS_INDEXES = hydraulics_simulation.Simulation.PHYTOMERS_INDEXES
#: concatenation of :attr:`T_INDEX` and :attr:`PHYTOMERS_INDEXES`
PHYTOMERS_T_INDEXES = hydraulics_simulation.Simulation.PHYTOMERS_T_INDEXES
#: phytomers post-processing variables
PHYTOMERS_POSTPROCESSING_VARIABLES = []
#: concatenation of :attr:`PHYTOMERS_T_INDEXES`, :attr:`PHYTOMERS_RUN_VARIABLES <cnmetabolism.simulation.Simulation.PHYTOMERS_RUN_VARIABLES>` and :attr:`PHYTOMERS_POSTPROCESSING_VARIABLES`
PHYTOMERS_RUN_POSTPROCESSING_VARIABLES = set(PHYTOMERS_T_INDEXES + hydraulics_simulation.Simulation.PHYTOMERS_RUN_VARIABLES + PHYTOMERS_POSTPROCESSING_VARIABLES)
#: the indexes to locate the organs in the modelled system
ORGANS_INDEXES = hydraulics_simulation.Simulation.ORGANS_INDEXES
#: concatenation of :attr:`T_INDEX` and :attr:`ORGANS_INDEXES`
ORGANS_T_INDEXES = hydraulics_simulation.Simulation.ORGANS_T_INDEXES
#: organs post-processing variables
ORGANS_POSTPROCESSING_VARIABLES = []
ORGANS_RUN_VARIABLES_ADDITIONAL = []
#: concatenation of :attr:`ORGANS_T_INDEXES`, :attr:`ORGANS_RUN_VARIABLES <cnmetabolism.simulation.Simulation.ORGANS_RUN_VARIABLES>` and :attr:`ORGANS_POSTPROCESSING_VARIABLES`
ORGANS_RUN_POSTPROCESSING_VARIABLES = set(ORGANS_T_INDEXES + hydraulics_simulation.Simulation.ORGANS_RUN_VARIABLES + ORGANS_POSTPROCESSING_VARIABLES + ORGANS_RUN_VARIABLES_ADDITIONAL)
#: the indexes to locate the hidden zones in the modelled system
HIDDENZONE_INDEXES = hydraulics_simulation.Simulation.HIDDENZONE_INDEXES
#: concatenation of :attr:`T_INDEX` and :attr:`HIDDENZONE_INDEXES`
HIDDENZONE_T_INDEXES = hydraulics_simulation.Simulation.HIDDENZONE_T_INDEXES
#: hidden zones post-processing variables
HIDDENZONE_POSTPROCESSING_VARIABLES = ['conc_solutes_vol', 'conc_solutes_mass', 'LER']
HIDDENZONE_RUN_VARIABLES_ADDITIONAL = []
#: concatenation of :attr:`HIDDENZONE_T_INDEXES`, :attr:`HIDDENZONE_RUN_VARIABLES <hydraulics.simulation.Simulation.HIDDENZONE_RUN_VARIABLES>` and :attr:`HIDDENZONE_POSTPROCESSING_VARIABLES`
HIDDENZONE_RUN_POSTPROCESSING_VARIABLES = HIDDENZONE_T_INDEXES + hydraulics_simulation.Simulation.HIDDENZONE_RUN_VARIABLES + HIDDENZONE_RUN_VARIABLES_ADDITIONAL + HIDDENZONE_POSTPROCESSING_VARIABLES
#: the indexes to locate the elements in the modelled system
ELEMENTS_INDEXES = hydraulics_simulation.Simulation.ELEMENTS_INDEXES
#: concatenation of :attr:`T_INDEX` and :attr:`ELEMENTS_INDEXES`
ELEMENTS_T_INDEXES = hydraulics_simulation.Simulation.ELEMENTS_T_INDEXES
#: elements post-processing variables
ELEMENTS_POSTPROCESSING_VARIABLES = []
ELEMENTS_RUN_VARIABLES_ADDITIONAL = []
#: concatenation of :attr:`ELEMENTS_T_INDEXES`, :attr:`ELEMENTS_RUN_VARIABLES <hydraulics.simulation.Simulation.ELEMENTS_RUN_VARIABLES>` and :attr:`ELEMENTS_POSTPROCESSING_VARIABLES`
ELEMENTS_RUN_POSTPROCESSING_VARIABLES = ELEMENTS_T_INDEXES + hydraulics_simulation.Simulation.ELEMENTS_RUN_VARIABLES + ELEMENTS_RUN_VARIABLES_ADDITIONAL + ELEMENTS_POSTPROCESSING_VARIABLES
#: the indexes to locate the soils in the modelled system
SOILS_INDEXES = hydraulics_simulation.Simulation.SOILS_INDEXES
#: concatenation of :attr:`T_INDEX` and :attr:`SOILS_INDEXES`
SOILS_T_INDEXES = hydraulics_simulation.Simulation.SOILS_T_INDEXES
#: soils post-processing variables
SOILS_POSTPROCESSING_VARIABLES = []
#: concatenation of :attr:`SOILS_T_INDEXES`, :attr:`SOILS_RUN_VARIABLES <cnmetabolism.simulation.Simulation.SOILS_RUN_VARIABLES>` and :attr:`SOILS_POSTPROCESSING_VARIABLES`
SOILS_RUN_POSTPROCESSING_VARIABLES = SOILS_T_INDEXES + hydraulics_simulation.Simulation.SOILS_RUN_VARIABLES + SOILS_POSTPROCESSING_VARIABLES
# ---------------------------------------------------
# POST-PROCESSING FUNCTIONS -
# DO NOT USE THEM DIRECTLY -
# ---------------------------------------------------
[docs]
class Roots:
"""
Post-processing to apply on Xylem outputs.
"""
pass
[docs]
class Xylem:
"""
Post-processing to apply on Xylem outputs.
"""
pass
[docs]
class HiddenZone:
"""
Post-processing to apply on HiddenZone outputs.
"""
def __init__(self):
pass
[docs]
@staticmethod
def calculate_LER(leaf_L, init_leaf_L, delta_t):
"""Calculates Leaf elongation rate in phase II
:param float leaf_L: Leaf length at time t (m)
:param float init_leaf_L: Leaf length at time t-1 (m)
:param float delta_t: Delta time (h)
:return: Leaf elongation rate (mm h-1)
:rtype: float
"""
LER = ((leaf_L - init_leaf_L) * 1E03) / delta_t
return LER
[docs]
@staticmethod
def calculate_conc_solutes_vol(sucrose, fructan, amino_acids, volume):
"""Volumic concentration of solutes used for osmotic water potential calculation
:param float sucrose: Amount of sucrose (µmol` C)
:param float amino_acids: Amount of amino acids (µmol` N)
:param float fructan: Amount of fructan (µmol` C)
:param float volume: Volume (m3)
:return: Solutes volumic concentration (mol m-3)
:rtype: float
"""
conc_solutes_vol = (sucrose / hydraulics_parameters.NB_C_SUCROSE + fructan / hydraulics_parameters.NB_C_SUCROSE + amino_acids / hydraulics_parameters.AMINO_ACIDS_N_RATIO) * 1E-06 / (volume * hydraulics_parameters.VSTORAGE)
return conc_solutes_vol
[docs]
@staticmethod
def calculate_conc_solutes_mass(fructan, sucrose, amino_acids, mstruct):
"""Massic concentration of solutes used for osmotic water potential calculation
:param float sucrose: Amount of sucrose (µmol` C)
:param float amino_acids: Amount of amino acids (µmol` N)
:param float fructan: Amount of fructan (µmol` C)
:param float mstruct: Structural mass (g)
:return: Solutes massic concentration (mol m-3)
:rtype: float
"""
conc_solutes_mass = (fructan + sucrose + amino_acids) * 1E-06 / mstruct
return conc_solutes_mass
[docs]
class Element:
"""
Post-processing to apply on Element outputs.
"""
pass
[docs]
class Organ:
"""
Post-processing to apply on Organ outputs.
"""
pass
# ------------------------------------------------------------------------------------------------
# POST-PROCESSING FRONT-END -
# PLEASE USE THIS FUNCTION TO APPLY POST-PROCESSING ON THE OUTPUT OF HYDRAULICS -
# ------------------------------------------------------------------------------------------------
[docs]
def postprocessing(plants_df=None, axes_df=None, metamers_df=None, hiddenzones_df=None, organs_df=None, elements_df=None, soils_df=None, delta_t=1):
"""
Compute post-processing from Hydraulics outputs, and format the post-processing to :class:`dataframes <pandas.DataFrame>`.
For each post-processing output dataframe:
* compute post-processing from Hydraulics outputs,
* concatenate Hydraulics outputs and post-processing and place the results in a jointed dataframe,
* reorder the columns of the dataframes according to
:attr:`HIDDENZONE_RUN_POSTPROCESSING_VARIABLES`, :attr:`ELEMENTS_RUN_POSTPROCESSING_VARIABLES`, :attr:`ORGAN_RUN_POSTPROCESSING_VARIABLES`
* and convert the indexes of plants and metamers to integers (if relevant).
:param pandas.DataFrame plants_df: Hydraulics outputs at plant scale (see :attr:`simulation.Simulation.PLANTS_RUN_VARIABLES`)
:param pandas.DataFrame axes_df: Hydraulics outputs at axis scale (see :attr:`simulation.Simulation.AXES_RUN_VARIABLES`)
:param pandas.DataFrame metamers_df: Hydraulics outputs at phytomer scale (see :attr:`simulation.Simulation.PHYTOMERS_RUN_VARIABLES`)
:param pandas.DataFrame hiddenzones_df: Hydraulics outputs at hidden zone scale (see :attr:`simulation.Simulation.HIDDENZONE_RUN_VARIABLES`)
:param pandas.DataFrame elements_df: Hydraulics outputs at element scale (see :attr:`simulation.Simulation.ELEMENTS_RUN_VARIABLES`)
:param pandas.DataFrame organs_df: Hydraulics outputs at xylem scale (see :attr:`simulation.Simulation. ORGAN_RUN_VARIABLES`)
:param pandas.DataFrame soils_df: Hydraulics outputs at soil scale (see :attr:`simulation.Simulation.SOILS_RUN_VARIABLES`)
:param float delta_t: Delta t between 2 outputs (in seconds).
:return: :class:`dataframes <pandas.DataFrame>` of post-processing for each scale:
* hidden zone (see :attr:`HIDDENZONE_RUN_POSTPROCESSING_VARIABLES`)
* element (see :attr:`ELEMENTS_RUN_POSTPROCESSING_VARIABLES`)
* xylem (see :attr:`XYLEM_RUN_POSTPROCESSING_VARIABLES`)
* and soil (see :attr:`SOILS_RUN_POSTPROCESSING_VARIABLES`)
:rtype tuple [pandas.DataFrame]
"""
returned_dataframes = []
# plants
if plants_df is not None:
pp_plants_df = pd.concat([plants_df, pd.DataFrame(columns=PLANTS_POSTPROCESSING_VARIABLES)], sort=False)
pp_plants_df = pp_plants_df.reindex(PLANTS_RUN_POSTPROCESSING_VARIABLES, axis=1, copy=False)
pp_plants_df['plant'] = pp_plants_df['plant'].astype(int)
returned_dataframes.append(pp_plants_df)
else:
returned_dataframes.append(pd.DataFrame({'A': []}))
# axes
if axes_df is not None:
axes_df = axes_df[axes_df['axis'] == 'MS'].copy() # TODO : Temporary !
pp_axes_df = pd.concat([axes_df, pd.DataFrame(columns=AXES_POSTPROCESSING_VARIABLES)], sort=False)
pp_axes_df = pp_axes_df.reindex(AXES_RUN_POSTPROCESSING_VARIABLES, axis=1, copy=False)
pp_axes_df.loc[:, 'plant_WC_DM'] = axes_df['plant_water_content'] / (axes_df['plant_water_content'] + axes_df['mstruct'])
# pp_axes_df['plant'] = pp_axes_df['plant'].astype(int)
returned_dataframes.append(pp_axes_df)
# metamers
if metamers_df is not None:
pp_metamers_df = pd.concat([metamers_df, pd.DataFrame(columns=PHYTOMERS_POSTPROCESSING_VARIABLES)], sort=False)
pp_metamers_df = pp_metamers_df.reindex(PHYTOMERS_RUN_POSTPROCESSING_VARIABLES, axis=1, copy=False)
pp_metamers_df[['plant', 'metamer']] = pp_metamers_df[['plant', 'metamer']].astype(int)
returned_dataframes.append(pp_metamers_df)
else:
returned_dataframes.append(pd.DataFrame({'A': []}))
# hidden zones
if hiddenzones_df is not None:
hiddenzones_df.loc[:, 'conc_solutes_mass'] = HiddenZone.calculate_conc_solutes_mass(hiddenzones_df['fructan'], hiddenzones_df['sucrose'], hiddenzones_df['amino_acids'], hiddenzones_df['mstruct'])
hiddenzones_df.loc[:, 'conc_solutes_vol'] = HiddenZone.calculate_conc_solutes_vol(hiddenzones_df['fructan'], hiddenzones_df['sucrose'], hiddenzones_df['amino_acids'], hiddenzones_df['volume'])
hiddenzones_df.loc[:, 'LER'] = HiddenZone.calculate_LER(hiddenzones_df['leaf_L'], hiddenzones_df['init_leaf_L'], delta_t)
pp_hiddenzones_df = pd.concat([hiddenzones_df, pd.DataFrame(columns=HIDDENZONE_POSTPROCESSING_VARIABLES)], sort=False)
pp_hiddenzones_df = pp_hiddenzones_df.reindex(columns=HIDDENZONE_RUN_POSTPROCESSING_VARIABLES, copy=False)
pp_hiddenzones_df[['plant', 'metamer']] = pp_hiddenzones_df[['plant', 'metamer']].astype(int)
returned_dataframes.append(pp_hiddenzones_df)
# elements
if elements_df is not None:
pp_elements_df = pd.concat([elements_df, pd.DataFrame(columns=ELEMENTS_POSTPROCESSING_VARIABLES)], sort=True)
pp_elements_df = pp_elements_df.reindex(columns=ELEMENTS_RUN_POSTPROCESSING_VARIABLES, copy=False)
grouped = elements_df.groupby('organ')
for organ_type, parameters_class in (('blade', hydraulics_parameters.LAMINA_ELEMENT_PARAMETERS), ('internode', hydraulics_parameters.INTERNODE_ELEMENT_PARAMETERS), ('sheath', hydraulics_parameters.SHEATH_ELEMENT_PARAMETERS)):
if organ_type not in grouped.groups:
continue
group = grouped.get_group(organ_type)
if len(group) == 0: # TODO: faire mm tri que dans simulation de cnmetabolism (surface nulle)
continue
pp_elements_df = pp_elements_df.reindex(columns=ELEMENTS_RUN_POSTPROCESSING_VARIABLES, copy=False)
pp_elements_df[['plant', 'metamer']] = pp_elements_df[['plant', 'metamer']].astype(int)
returned_dataframes.append(pp_elements_df)
# organs
if organs_df is not None and axes_df is not None:
pp_organs_df = pd.concat([organs_df, pd.DataFrame(columns=ORGANS_POSTPROCESSING_VARIABLES)], sort=False)
pp_organs_df = pp_organs_df.reindex(columns=ORGANS_RUN_POSTPROCESSING_VARIABLES, copy=False)
pp_organs_df['plant'] = pp_organs_df['plant'].astype(int)
returned_dataframes.append(pp_organs_df)
# soils
if soils_df is not None:
pp_soils_df = pd.concat([soils_df, pd.DataFrame(columns=SOILS_POSTPROCESSING_VARIABLES)])
pp_soils_df = pp_soils_df.reindex(columns=SOILS_RUN_POSTPROCESSING_VARIABLES, copy=False)
pp_soils_df[['plant']] = pp_soils_df[['plant']].astype(int)
returned_dataframes.append(pp_soils_df)
else:
returned_dataframes.append(pd.DataFrame({'A': []}))
return tuple(returned_dataframes)
# ---------------------------------------------------------------------
# GRAPHS GENERATION FRONT-END -
# PLEASE USE THIS FUNCTION FOR THE GENERATION OF GRAPHS -
# ---------------------------------------------------------------------
[docs]
def generate_graphs(axes_df=None, hiddenzones_df=None, organs_df=None, elements_df=None, soils_df=None, meteo_data=None, graphs_dirpath='.'):
"""
Generate graphs to validate the outputs of Hydraulics, and save them in directory `graphs_dirpath`.
:param pandas.DataFrame axes_df: Hydraulics outputs and post-processing at axis scale (see :attr:`PLANTS_RUN_POSTPROCESSING_VARIABLES`)
:param pandas.DataFrame hiddenzones_df: Hydraulics outputs at hidden zone scale (see :attr:`HIDDENZONE_RUN_POSTPROCESSING_VARIABLES`)
:param pandas.DataFrame elements_df: Hydraulics outputs at element scale (see :attr:`ELEMENTS_RUN_POSTPROCESSING_VARIABLES`)
:param pandas.DataFrame organs_df: Hydraulics outputs at organ scale (see :attr:`ORGANS_RUN_POSTPROCESSING_VARIABLES`)
:param pandas.DataFrame soils_df: Hydraulics outputs at soil scale (see :attr:`SOILS_RUN_POSTPROCESSING_VARIABLES`)
:param pandas.DataFrame meteo_data: the meteo dataframe having the mapping between t (hours) and calendar dates
:param str graphs_dirpath: the path of the directory to save the generated graphs
"""
x_name = 't'
x_label = 'Time (Hour)'
colors = ['blue', 'darkorange', 'green', 'red', 'darkviolet', 'gold', 'magenta', 'brown', 'darkcyan', 'grey', 'lime']
colors = colors + colors + colors + colors + colors
# 1) Photosynthetic organs
if elements_df is not None:
graph_variables_ph_elements = {'age': u'Age (°Cd)', 'organ_volume': 'Volume of organ based on dimensions (m3)', 'epsilon_volume': 'Volumetric elasticity (Mpa)', 'Total_Transpiration_turgor': u'Total transpiration of turgor model (g H2O)',
'osmotic_water_potential': u'Osmotic water potential (MPa)', 'thickness': u'Thickness (m)', 'water_potential': u'Total water potential (MPa)',
'turgor_water_potential': u'Turgor water potential (MPa)', 'water_content': u'Water content (g)', 'water_influx': u'Water flow from Xylem (g)', 'width': u'Width (m)', 'WC_mstruct': u'ratio WC_mstruct (%)',
'resistance': u'Resistance (MPa s g$^{-1}$)', 'volume': u'Volume (m3)'}
for org_ph in (['blade'], ['sheath'], ['internode']):
for variable_name, variable_label in graph_variables_ph_elements.items():
graph_name = variable_name + '_' + '_'.join(org_ph) + '.PNG'
integration_tools.plot_outputs(elements_df,
x_name=x_name,
y_name=variable_name,
x_label=x_label,
y_label=variable_label,
colors=[colors[i - 1] for i in elements_df.metamer.unique().tolist()],
filters={'organ': org_ph, 'axis': 'MS'},
plot_filepath=os.path.join(graphs_dirpath, graph_name),
meteo_data=meteo_data,
explicit_label=False)
# 2) Hidden zones
if hiddenzones_df is not None:
graph_variables_hiddenzones = {'delta_hiddenzone_dimensions_plastic': u'dl / dt plastic (mm h-1)', 'LER': u'LER in phase II (mm h-1)', 'conc_solutes_vol': u'conc_solutes_vol', 'conc_solutes_mass': u'conc_solutes_mass',
'length_hz_En': u'Length of HZ after En (m)', 'organ_volume': u'Volume of hz based on dimensions (m3)', 'phi_volume': u'Volumetric extensibility (MPa-1 h-1) ', 'epsilon_volume': u'Volumetric elasticity (Mpa)', 'leaf_pseudo_age': u'Leaf pseudo age (°Cd)',
'phi_length': u'Extensibility parameter for length (Mpa-1 h-1)', 'phi_width': u'Extensibility parameter for width (Mpa-1 h-1)', 'phi_thickness': u'Extensibility parameter for thickness (Mpa-1 h-1)',
'length': u'Length of hz (m)', 'hiddenzone_age': u'Age (s)',
'osmotic_water_potential': u'Osmotic water potential (MPa)', 'width': u'Width (m)', 'water_potential': u'Total water potential (MPa)',
'turgor_water_potential': u'Turgor water potential (MPa)', 'water_content': u'Water content (g)', 'water_influx': u'Water flow Xylem (g)',
'resistance': u'Resistance (MPa s g$^{-1}$)', 'thickness': u'Thickness (m)', 'volume': u'Volume (m3)', 'WC_mstruct': u'ratio WC_mstruct'}
for variable_name, variable_label in graph_variables_hiddenzones.items():
graph_name = variable_name + '_hz' + '.PNG'
integration_tools.plot_outputs(hiddenzones_df,
x_name=x_name,
y_name=variable_name,
x_label=x_label,
y_label=variable_label,
colors=[colors[i - 1] for i in hiddenzones_df.metamer.unique().tolist()],
filters={'plant': 1, 'axis': 'MS'},
plot_filepath=os.path.join(graphs_dirpath, graph_name),
meteo_data=meteo_data,
explicit_label=False)
# 3) Roots and xylem
if organs_df is not None:
graph_variables_organs = {'water_potential': u'Total water potential (MPa)'}
for org in (['roots'], ['xylem']):
for variable_name, variable_label in graph_variables_organs.items():
graph_name = variable_name + '_' + '_'.join(org) + '.PNG'
integration_tools.plot_outputs(organs_df,
x_name=x_name,
y_name=variable_name,
x_label=x_label,
y_label=variable_label,
colors=['blue'],
filters={'organ': org},
plot_filepath=os.path.join(graphs_dirpath, graph_name),
meteo_data=meteo_data,
explicit_label=False)
# 4) Axes
graph_variables_axes = {'Total_Transpiration_turgor': u'Total transpiration from turgor model (g H2O)', 'Growth': u'Growth (g H2O)',
'water_influx': u' Water flux from xylem to HZ and photosynthetic organs (g H2O)', 'plant_water_content': u'Total water content of the plant (g H2O)',
'plant_WC_DM': u'Ratio of plant water content per structural mass (%)'}
for variable_name, variable_label in graph_variables_axes.items():
graph_name = variable_name + '_axis' + '.PNG'
integration_tools.plot_outputs(axes_df,
x_name=x_name,
y_name=variable_name,
x_label=x_label,
y_label=variable_label,
colors=['blue'],
filters={'plant': 1, 'axis': 'MS'},
plot_filepath=os.path.join(graphs_dirpath, graph_name),
meteo_data=meteo_data,
explicit_label=False)
# 5) Soil
if soils_df is not None:
_, (ax1) = plt.subplots(1)
SRWC = soils_df['SRWC']
ax1.plot(soils_df['t'], SRWC)
ax1.set_ylabel(u'SRWC')
ax1.set_xlabel('Time (hour)')
ax1.set_title = 'SRWC'
ax1.set_ylim(bottom=0)
plt.savefig(os.path.join(graphs_dirpath, 'SRWC.PNG'), format='PNG', bbox_inches='tight')
plt.close()
_, (ax1) = plt.subplots(1)
water_potential = soils_df['water_potential']
ax1.plot(soils_df['t'], water_potential)
ax1.set_ylabel(u'Soil water potential (MPa)')
ax1.set_xlabel('Time (hour)')
ax1.set_title = 'Soil water potential'
#ax1.set_ylim(bottom=0)
plt.savefig(os.path.join(graphs_dirpath, 'Soil water potential.PNG'), format='PNG', bbox_inches='tight')
plt.close()