Source code for CompartmentalSystems.cs_plotter

import matplotlib.patches as mpatches
import numpy as np
from sympy import Symbol, latex


[docs]class Pool(): def __init__( self, x, y, size, pool_color, pool_alpha, pipe_alpha, connectionstyle, arrowstyle, mutation_scale ): self.x = x self.y = y self.size = size self.pool_color = pool_color self.pool_alpha = pool_alpha self.pipe_alpha = pipe_alpha self.connectionstyle = connectionstyle self.arrowstyle = arrowstyle self.mutation_scale = mutation_scale
[docs] def plot(self, ax): ax.add_patch( mpatches.Circle( (self.x, self.y), self.size, alpha=self.pool_alpha, color=self.pool_color ) )
[docs] def plot_name(self, ax, name, fontsize): ax.text( self.x, self.y, name, fontsize = fontsize, horizontalalignment='center', verticalalignment='center' )
[docs] def plot_input_flux(self, ax, color): z1 = self.x-0.5 + (self.y-0.5)*1j arg1 = np.angle(z1) - np.pi/6 z1 = z1 + np.exp(1j*arg1) * self.size x1 = 0.5+z1.real y1 = 0.5+z1.imag z2 = z1 + np.exp(1j * arg1) * self.size * 1.0 x2 = 0.5+z2.real y2 = 0.5+z2.imag ax.add_patch( mpatches.FancyArrowPatch( (x2,y2), (x1,y1), connectionstyle=self.connectionstyle, arrowstyle=self.arrowstyle, mutation_scale=self.mutation_scale, alpha=self.pipe_alpha, color=color ) )
[docs] def plot_output_flux(self, ax, color): z1 = self.x-0.5 + (self.y-0.5)*1j arg1 = np.angle(z1) + np.pi/6 z1 = z1 + np.exp(1j*arg1) * self.size x1 = 0.5+z1.real y1 = 0.5+z1.imag z2 = z1 + np.exp(1j * arg1) * self.size *1.0 x2 = 0.5+z2.real y2 = 0.5+z2.imag ax.add_patch( mpatches.FancyArrowPatch( (x1,y1), (x2,y2), arrowstyle=self.arrowstyle, connectionstyle=self.connectionstyle, mutation_scale=self.mutation_scale, alpha=self.pipe_alpha, color=color ) )
[docs] def plot_internal_flux_to(self, ax, pool_to, color): r=self.size z1 = (self.x-0.5) + (self.y-0.5) * 1j z2 = (pool_to.x-0.5) + (pool_to.y-0.5) * 1j arg1 = np.angle(z2-z1) - np.pi/20 z1 = z1+np.exp(1j*arg1)*r arg2 = np.angle(z1-z2) + np.pi/20 z2 = z2+np.exp(1j*arg2)*r x1 = 0.5+z1.real y1 = 0.5+z1.imag x2 = 0.5+z2.real y2 = 0.5+z2.imag ax.add_patch( mpatches.FancyArrowPatch( (x1,y1), (x2,y2), connectionstyle=self.connectionstyle, arrowstyle=self.arrowstyle, mutation_scale=self.mutation_scale, alpha=self.pipe_alpha, color=color ) )
[docs]class CSPlotter(): def __init__( self, state_vector, inputs, outputs, internal_fluxes, pipe_colors = { 'linear': 'blue', 'nonlinear': 'green', 'no state dependence': 'red' }, visible_pool_names = True, pool_size_scale_factor = 1, pool_color = 'blue', pool_alpha = 0.3, pipe_alpha = 0.5, connectionstyle = 'arc3, rad=0.1', arrowstyle = 'simple', mutation_scale = 50, fontsize = 24 ): self.state_vector = state_vector self.input_fluxes= inputs self.output_fluxes = outputs self.internal_fluxes = internal_fluxes self.visible_pool_names= visible_pool_names self.pool_size_scale_factor = pool_size_scale_factor self.pipe_colors = pipe_colors self.pool_color = pool_color self.pool_alpha = pool_alpha self.pipe_alpha = pipe_alpha self.connectionstyle = connectionstyle self.arrowstyle = arrowstyle self.mutation_scale = mutation_scale self.fontsize = fontsize
[docs] def plot_pools_and_fluxes(self, ax): nr_pools = len(self.state_vector) inputs = self.input_fluxes outputs = self.output_fluxes internal_fluxes = self.internal_fluxes base_r = 0.1 + (0.5-0.1)/10*nr_pools if nr_pools > 1: r = base_r * (1-np.exp(1j*2*np.pi/nr_pools)) r = abs(r) / 2 * 0.6 r = min(r, (0.5-base_r)*0.5) else: r = base_r * 0.5 r = abs(r) r = r * self.pool_size_scale_factor pools = [] for i in range(nr_pools): z = base_r * np.exp(i*2*np.pi/nr_pools*1j) x = 0.5 - z.real y = 0.5 + z.imag pool = Pool( x, y, r, self.pool_color, self.pool_alpha, self.pipe_alpha, self.connectionstyle, self.arrowstyle, self.mutation_scale ) pool.plot(ax) if self.visible_pool_names: pool_name = Symbol(str(self.state_vector[i])) pool.plot_name(ax, "$"+latex(pool_name)+"$", self.fontsize) # plot influx if i in inputs.keys(): pool.plot_input_flux( ax, self.pipe_colors[inputs[i]] ) # plot outflux if i in outputs.keys(): pool.plot_output_flux( ax, self.pipe_colors[outputs[i]] ) pools.append(pool) # plot internal fluxes for key in internal_fluxes.keys(): i, j = key pools[i].plot_internal_flux_to( ax, pools[j], self.pipe_colors[internal_fluxes[key]] )
[docs] def legend(self, ax): legend_descs = [] legend_colors = [] for desc, col in self.pipe_colors.items(): legend_descs.append(desc) legend_colors.append( mpatches.FancyArrowPatch( (0,0), (1,1), connectionstyle=self.connectionstyle, arrowstyle=self.arrowstyle, mutation_scale=self.mutation_scale, alpha=self.pipe_alpha, color=col ) ) ax.legend(legend_colors, legend_descs, loc='upper center', bbox_to_anchor=(0.5, 1.1), ncol = 3)