fmdtools.analyze.graph

Package for graph representations and analysis of model structures.

The graph sub-package is used to graphically represent models and has the following modules:

fmdtools.analyze.graph.label

Defines label arguments for graph plotting.

fmdtools.analyze.graph.style

Defines style arguments for plotting graphs.

fmdtools.analyze.graph.base

Provides representations and visualizations of a model graph structure.

fmdtools.analyze.graph.model

Module for generating graphs from models.

fmdtools.analyze.graph.label

Defines label arguments for graph plotting.

Has classes:

  • LabelStyle: Holds kwargs for nx.draw_networkx_labels to be applied to labels

  • EdgeLabelStyle: Controls edge labels to ensure they do not rotate

  • Labels: Defines a set of labels to be drawn using draw_networkx_labels.

And Functions: - label_for_entry(): Gets the label from an nx.graph for a given entry.

class fmdtools.analyze.graph.label.EdgeLabelStyle

Bases: LabelStyle

Holds kwargs for nx.draw_networkx_edge_labels.

alpha: float
bbox: dict
clip_on: bool
font_color: str
font_size: int
font_weight: str
horizontalalignment: str
rotate: bool
verticalalignment: str
class fmdtools.analyze.graph.label.LabelStyle

Bases: dataobject

Holds kwargs for nx.draw_networkx_labels to be applied as a style for labels.

alpha: float
bbox: dict
clip_on: bool
font_color: str
font_size: int
font_weight: str
gv_align(text)
horizontalalignment: str
kwargs()

Return kwargs for nx.draw_networkx_labels.

verticalalignment: str
class fmdtools.analyze.graph.label.Labels

Bases: dataobject

Define a set of labels to be drawn using draw_networkx_labels.

Labels have three distinct parts:

  • title (upper text for the node/edge)

  • title2 (if provided, uppder text for the node/edge after a colon)

  • subtext (lower text of the node/edge)

Title and subtext may both be given different LabelStyles.

draw_nx_edges(g, pos, ax=None)

Draw edge labels for a given graph.

draw_nx_nodes(g, pos, ax=None)

Draw node labels for a given graph.

from_iterator(iterator, LabStyle, title='shortname', title2='', subtext='', **node_label_styles)

Construct the labels from an interator (nodes or edges).

Parameters:
  • g (nx.graph) – Networkx graph structure to create labels for

  • iterator (nx.graph.nodes/edges) – Property to iterate over (e.g., nodes or edges)

  • LabStyle (class) – Class to use for label styles (e.g., LabelStyle or EdgeStyle)

  • title (str, optional) – entry for title text. (See label_for_entry() for options). The default is ‘id’.

  • title2 (str, optional) – entry for title text after the colon. (See label_for_entry() for options). The default is ‘’.

  • subtext (str, optional) – entry for the subtext. (See label_for_entry() for options). The default is ‘’.

  • **node_label_styles (dict) – LabStyle arguments to overwrite.

Returns:

labs – Labels corresponding to the given inputs

Return type:

Labels

iter_groups()

Return groups to iterate through when calling nx.draw_labels.

make_gv_label(node)

Make the label for graphviz for a given node.

subtext: dict
subtext_style: LabelStyle
title: dict
title_style: LabelStyle
fmdtools.analyze.graph.label.label_for_entry(g, iterator, entryname)

Create the label dictionary for a given entry value of interest.

Parameters:
  • g (nx.graph) – Networkx graph structure to create labels for

  • iterator (nx.graph.nodes/edges) – Property to iterate over (e.g., nodes or edges)

  • entryname (str) –

    Property to get from the graph attributes. Options are:

    • ’id’ : The full name of the node/edge

    • ’shortname’ :The short name of the node/edge (after .xx)

    • ’last’ : The last part (after all “_” characters) of the name of the node/edge

    • ’nodetype’/’edgetype’ : The type property of the node or edge.

    • ’faults_and_indicators’ : Fault and indicator properties from the node/edge

    • <str> : Any other property corresponding to the key in the node/edge dict

Returns:

entryvals – Dictionary of values to show for the given entry

Return type:

dict

fmdtools.analyze.graph.label.make_lastname(name)
fmdtools.analyze.graph.label.make_shortname(name)
fmdtools.analyze.graph.label.shorten_name(name, rem_ind=0)

fmdtools.analyze.graph.style

The style module defines graph attributes (nodes and edges) are visually represented as a part of an overall diagram.

Generally, it is the intent of fmdtools to comply with the FRDL specification as much as possible, however, graphviz and networkx limit our ability to comply fully. Below we show how each FRDL construct is visually represented in fmdtools:

Edges

Construct

FRDL

graphviz

networkx

Flow Connection

frdl_flowcon

gv_flowc

nx_flowc

Activation

frdl_activ

gv_activ

nx_activ

Flow Propagation

frdl_prop

N/A

N/A

Weak Connection

N/A

gv_conn

nx_conn

Nodes

Construct

FRDL

graphviz

networkx

Flow

frdl_flow

gv_flow

nx_flow

MultiFlow

frdl_mflow

gv_mflow

nx_mflow

CommsFlow

frdl_cflow

gv_cflow

nx_cflow

Function

frdl_fxn

gv_fxn

nx_fxn

Action

frdl_act

gv_act

nx_act

Component

frdl_com

gv_com

nx_com

Container

N/A

gv_con

nx_con

Architecture

N/A

gv_arch

nx_arch

Defines style arguments for plotting graphs.

Has Classes:

And functions:

class fmdtools.analyze.graph.style.ActionNodeStyle(*args, styles={}, **kwargs)

Bases: BlockNodeStyle

Style representing Actions.

gv_color: str
gv_fillcolor: str
gv_penwidth: str
gv_shape: str
gv_style: str
nx_cmap: Colormap
nx_edgecolors: str
nx_linewidths: int
nx_node_color: str
nx_node_shape: str
nx_node_size: int
nx_vmax: float
nx_vmin: float
class fmdtools.analyze.graph.style.ActivationEdgeStyle(*args, styles={}, **kwargs)

Bases: EdgeStyle

EdgeStyle representing activation/conditions.

gv_arrowhead: str
gv_color: str
gv_style: str
nx_arrows: bool
nx_arrowsize: int
nx_arrowstyle: str
nx_edge_color: str
nx_style: str
class fmdtools.analyze.graph.style.ArchitectureNodeStyle(*args, styles={}, **kwargs)

Bases: NodeStyle

Style representing Actions.

gv_color: str
gv_fillcolor: str
gv_shape: str
gv_style: str
nx_cmap: Colormap
nx_edgecolors: str
nx_node_color: str
nx_node_shape: str
nx_node_size: int
nx_vmax: float
nx_vmin: float
class fmdtools.analyze.graph.style.BaseStyle(*args, styles={}, **kwargs)

Bases: dataobject

Base class to define node/edge styles.

gv_kwargs()

Return keyword arguments for dot.edge.

nx_kwargs()

Return kwargs to nx.draw_networkx_nodes.

set_styles(**styles)

Modify the style based on a modifier.

class fmdtools.analyze.graph.style.BlockNodeStyle(*args, styles={}, **kwargs)

Bases: NodeStyle

Style representing Functions.

gv_color: str
gv_fillcolor: str
gv_penwidth: str
gv_shape = 'rectangle'
nx_cmap: Colormap
nx_edgecolors: str
nx_linewidths: int
nx_node_color: str
nx_node_shape: str
nx_node_size: int
nx_vmax: float
nx_vmin: float
class fmdtools.analyze.graph.style.CommsFlowNodeStyle(*args, styles={}, **kwargs)

Bases: NodeStyle

Style representing CommsFlow objects.

gv_color: str
gv_fillcolor: str
gv_penwidth: str
gv_shape: str
gv_style: str
nx_cmap: Colormap
nx_edgecolors: str
nx_linewidths: int
nx_node_color: str
nx_node_shape: str
nx_node_size: int
nx_vmax: float
nx_vmin: float
class fmdtools.analyze.graph.style.ComponentNodeStyle(*args, styles={}, **kwargs)

Bases: NodeStyle

Style representing Components.

gv_color: str
gv_fillcolor: str
gv_shape: str
gv_style: str
nx_cmap: Colormap
nx_edgecolors: str
nx_node_color: str
nx_node_size: int
nx_vmax: float
nx_vmin: float
class fmdtools.analyze.graph.style.ConnectionEdgeStyle(*args, styles={}, **kwargs)

Bases: EdgeStyle

EdgeStyle representing activation/conditions.

gv_arrowhead: str
gv_color: str
gv_style: str
nx_arrows: bool
nx_arrowsize: int
nx_arrowstyle: str
nx_edge_color: str
nx_style: str
class fmdtools.analyze.graph.style.ContainerNodeStyle(*args, styles={}, **kwargs)

Bases: NodeStyle

Style representing containers.

gv_color: str
gv_fillcolor: str
gv_penwidth: str
gv_shape: str
gv_style: str
nx_cmap: Colormap
nx_edgecolors: str
nx_linewidths: int
nx_node_color: str
nx_node_shape: str
nx_node_size: int
nx_vmax: float
nx_vmin: float
class fmdtools.analyze.graph.style.ContainmentEdgeStyle(*args, styles={}, **kwargs)

Bases: EdgeStyle

EdgeStyle representing containment.

gv_arrowhead: str
gv_arrowtail: str
gv_color: str
gv_dir: str
gv_style: str
nx_arrows: bool
nx_arrowsize: int
nx_arrowstyle: str
nx_edge_color: str
nx_style: str
class fmdtools.analyze.graph.style.EdgeStyle(*args, styles={}, **kwargs)

Bases: BaseStyle

Define style to use to represent an edge.

Holds kwargs for nx.draw_networkx_edges in nx_arg and for graphviz in gv_arg.

Parameters:
  • nx_edge_color (str) – Color to represent edges with. Default is ‘black’.

  • nx_style (str) – Linestyle to represent edges with. Default is ‘solid’.

  • nx_arrows (bool) – Whether to include arrows. Default is False.

  • nx_arrowstyle (bool) – Arrow stle to use. Default is ‘-|>’.

  • nx_arrowsize (int) – Size of arrows to use. Default is 15.

  • gv_arrowhead (str) – Graphviz arrowhead.

  • gv_color (str) – Graphviz color.

  • gv_style (str) – Graphviz line style.

  • modifiers (dict) – Modifiers to previous parameters to apply based on particular styles.

draw_nx(g, pos, edges, label='', ax='')

Draw the edges of a graph with networkx.

gv_arrowhead = 'open'
gv_color = 'black'
gv_style = 'solid'
modifiers = {'active': {'gv_color': 'green', 'nx_edge_color': 'green'}, 'degraded': {'gv_color': 'orange', 'nx_edge_color': 'orange'}}
nx_arrows = False
nx_arrowsize = 15
nx_arrowstyle = '-|>'
nx_edge_color = 'black'
nx_kwargs()

Return the style-defined arguments for nx.draw_networkx_edges.v.

nx_legend_line(legend_label='')

Return mlines.Line2D patch for legend.

nx_style = 'solid'
show_gv(disp=True, saveas='')

Show how the edge will look in graphviz.

show_nx(fig=None, ax=None, figsize=(1, 1), withlegend=False, saveas='')

Show how the edge will look in networkx.

class fmdtools.analyze.graph.style.FlowEdgeStyle(*args, styles={}, **kwargs)

Bases: EdgeStyle

EdgeStyle representing flows sharing.

Examples

>>> FlowEdgeStyle(nx_arrows=False).nx_kwargs()
{'edge_color': 'black', 'style': 'solid', 'arrows': False}
>>> FlowEdgeStyle(nx_arrows=True).nx_kwargs()
{'edge_color': 'black', 'style': 'solid', 'arrows': True, 'arrowstyle': '-|>', 'arrowsize': 15}
gv_arrowhead: str
gv_arrowtail: str
gv_color: str
gv_dir: str
gv_style: str
nx_arrows: bool
nx_arrowsize: int
nx_arrowstyle: str
nx_edge_color: str
nx_style: str
class fmdtools.analyze.graph.style.FlowNodeStyle(*args, styles={}, **kwargs)

Bases: NodeStyle

Style representing Flow objects.

gv_color: str
gv_fillcolor: str
gv_penwidth: str
gv_shape: str
gv_style: str
nx_cmap: Colormap
nx_edgecolors: str
nx_linewidths: int
nx_node_color: str
nx_node_shape: str
nx_node_size: int
nx_vmax: float
nx_vmin: float
class fmdtools.analyze.graph.style.FunctionNodeStyle(*args, styles={}, **kwargs)

Bases: BlockNodeStyle

Style representing Functions.

gv_color: str
gv_fillcolor: str
gv_penwidth: str
gv_shape: str
gv_style: str
nx_cmap: Colormap
nx_edgecolors: str
nx_linewidths: int
nx_node_color: str
nx_node_shape: str
nx_node_size: int
nx_vmax: float
nx_vmin: float
class fmdtools.analyze.graph.style.InheritanceEdgeStyle(*args, styles={}, **kwargs)

Bases: EdgeStyle

EdgeStyle representing inheritance.

gv_arrowhead: str
gv_color: str
gv_style: str
nx_arrows: bool
nx_arrowsize: int
nx_arrowstyle: str
nx_edge_color: str
nx_style: str
class fmdtools.analyze.graph.style.MethodNodeStyle(nx_node_color:str='lightgrey', nx_node_size:int=500, nx_edgecolors:str='grey', nx_cmap:Colormap, nx_vmin:float, nx_vmax:float, gv_fillcolor:str='lightgrey', gv_color:str='grey', nx_node_shape:str='d', nx_linewidths:int=0, gv_style:str='filled', gv_shape:str='component', gv_penwidth:str='1')

Bases: NodeStyle

Create class MethodNodeStyle instance

gv_color: str
gv_fillcolor: str
gv_penwidth: str
gv_shape: str
gv_style: str
nx_cmap: Colormap
nx_edgecolors: str
nx_linewidths: int
nx_node_color: str
nx_node_shape: str
nx_node_size: int
nx_vmax: float
nx_vmin: float
class fmdtools.analyze.graph.style.MultiFlowNodeStyle(*args, styles={}, **kwargs)

Bases: NodeStyle

Style representing MultiFlow objects.

gv_color: str
gv_fillcolor: str
gv_penwidth: str
gv_shape: str
gv_style: str
nx_cmap: Colormap
nx_edgecolors: str
nx_linewidths: int
nx_node_color: str
nx_node_shape: str
nx_node_size: int
nx_vmax: float
nx_vmin: float
class fmdtools.analyze.graph.style.NodeStyle(*args, styles={}, **kwargs)

Bases: BaseStyle

Define style to use to represent an edge.

Holds kwargs for nx.draw_networkx_nodes in nx_arg and for graphviz in gv_arg.

Parameters:
  • nx_node_shape (str) – Node shape to networkx. Extended by subclasses.

  • nx_lindwidths (int) – Width of node edge in networkx. Extended by subclasses.

  • nx_node_color (str) – Node color to networkx.

  • nx_node_size (int) – Node size in networkx.

  • nx_edgecolors (str) – Edge color to networkx.

  • nx_cmap (str) – Colormap to use in networkx.

  • gv_shape (str) – Node shape to graphviz. Extended by subclasses.

  • gv_penwidth (str) – Width of node edge in graphviz. Extended by subclasses.

  • gv_style (str) – Style of node in graphviz. Default is ‘filled’.

  • gv_fillcolor (str) – Fill color in graphviz. Default is ‘lightgrey’.

  • gv_color (str) – Edge color in graphviz. Default is ‘grey’.

  • modifiers (dict) – Modifiers to previous parameters to apply based on particular styles.

draw_nx(g, pos, nodes, label='', ax=None)

Draw the nodes using networkx.

gv_color: str
gv_fillcolor: str
gv_penwidth = '0'
gv_shape = 'ellipse'
gv_style = 'filled'
modifiers = {'active': {'gv_fillcolor': 'green', 'nx_node_color': 'green'}, 'degraded': {'gv_fillcolor': 'orange', 'nx_node_color': 'orange'}, 'dynamic': {'gv_color': 'teal', 'nx_edgecolors': 'teal'}, 'faulty': {'gv_color': 'red', 'nx_edgecolors': 'red'}, 'high_degree_nodes': {'gv_fillcolor': 'red', 'nx_node_color': 'red'}, 'static': {'gv_fillcolor': 'cyan', 'nx_node_color': 'cyan'}}
nx_cmap: Colormap
nx_edgecolors: str
nx_linewidths = 0
nx_node_color: str
nx_node_shape = 'o'
nx_node_size: int
nx_vmax: float
nx_vmin: float
show_gv(disp=True, saveas='')

Show how the edge will look in graphviz.

show_nx(fig=None, ax=None, figsize=(1, 1), withlegend=False, saveas='')

Show how the node will look in networkx.

class fmdtools.analyze.graph.style.OtherNodeStyle(*args, styles={}, **kwargs)

Bases: NodeStyle

Style representing other properties.

gv_color: str
gv_fillcolor: str
gv_penwidth: str
gv_shape: str
gv_style: str
nx_cmap: Colormap
nx_edgecolors: str
nx_linewidths: int
nx_node_color: str
nx_node_shape: str
nx_node_size: int
nx_vmax: float
nx_vmin: float
fmdtools.analyze.graph.style.edge_style_factory(style_tag, styles={}, **kwargs)

Get the appropriate EdgeStyle for networkx plotting.

Parameters:
  • style_tag (str) – Tag defining the type of edge (e.g. ‘flow’, ‘activation’, etc.)

  • styles (dict) – edge_styles based on style membership

  • **kwargs (kwargs) – Additional keyword arguments for the EdgeStyle

Examples

>>> loc = mod_prefix()
>>> fs = edge_style_factory('flow')
>>> fig, ax = fs.show_nx(saveas=loc+'nx_flowconnection.svg')
>>> sv = fs.show_gv(disp=False, saveas=loc+'gv_flowconnection.svg')
>>> a_s = edge_style_factory('activation')
>>> fig, ax = a_s.show_nx(saveas=loc+'nx_activation.svg')
>>> sv = a_s.show_gv(disp=False, saveas=loc+'gv_activation.svg')
>>> c_s = edge_style_factory('containment')
>>> fig, ax = c_s.show_nx(saveas=loc+'nx_containment.svg')
>>> sv = c_s.show_gv(disp=False, saveas=loc+'gv_containment.svg')
>>> cs = edge_style_factory('connection')
>>> fig, ax = cs.show_nx(saveas=loc+'nx_connection.svg')
>>> sv = cs.show_gv(disp=False, saveas=loc+'gv_connection.svg')
fmdtools.analyze.graph.style.gv_import_check()

Check if graphviz is installed on the system before plotting.

fmdtools.analyze.graph.style.gv_plot_ending(dot, disp=True, saveas='')

Add additional options for gv plots.

fmdtools.analyze.graph.style.mod_prefix()

Fix for doctest saving–changes save location.

fmdtools.analyze.graph.style.node_style_factory(style_tag, styles={}, **kwargs)

Get the keywords for networkx plotting.

Parameters:
  • styles (dict) – edge_styles/node_styles

  • label (tuple) – tuple of tag values to create the keywords for

Examples

>>> loc = mod_prefix()
>>> fs = node_style_factory('flow')
>>> fig, ax = fs.show_nx(saveas=loc+'nx_flow.svg')
>>> sv = fs.show_gv(disp=False, saveas=loc+'gv_flow.svg')
>>> ms = node_style_factory('multiflow')
>>> fig, ax = ms.show_nx(saveas=loc+'nx_multiflow.svg')
>>> sv = ms.show_gv(disp=False, saveas=loc+'gv_multiflow.svg')
>>> cs = node_style_factory('commsflow')
>>> fig, ax = cs.show_nx(saveas=loc+'nx_commsflow.svg')
>>> sv = cs.show_gv(disp=False, saveas=loc+'gv_commsflow.svg')
>>> fs = node_style_factory('function')
>>> fig, ax = fs.show_nx(saveas=loc+'nx_function.svg')
>>> sv = fs.show_gv(disp=False, saveas=loc+'gv_function.svg')
>>> a_s = node_style_factory('action')
>>> fig, ax = a_s.show_nx(saveas=loc+'nx_action.svg')
>>> sv = a_s.show_gv(disp=False, saveas=loc+'gv_action.svg')
>>> cs = node_style_factory('component')
>>> fig, ax = cs.show_nx(saveas=loc+'nx_component.svg')
>>> sv = cs.show_gv(disp=False, saveas=loc+'gv_component.svg')
>>> cs = node_style_factory('container')
>>> fig, ax = cs.show_nx(saveas=loc+'nx_container.svg')
>>> sv = cs.show_gv(disp=False, saveas=loc+'gv_container.svg')
>>> a_s = node_style_factory('architecture')
>>> fig, ax = a_s.show_nx(saveas=loc+'nx_architecture.svg')
>>> sv = a_s.show_gv(disp=False, saveas=loc+'gv_architecture.svg')
fmdtools.analyze.graph.style.nx_plot_ending(fig, ax, title='', withlegend=True, saveas='', **leg_kwargs)

Add additional options for nx plot.

fmdtools.analyze.graph.style.save_dot(dot, saveas='')

Save a graphviz diagram.

fmdtools.analyze.graph.style.to_legend_label(group_label, style_labels)

Create a legend label string for the group corresponding to style_labels.

Parameters:
  • group_label (tuple) – tuple defining the group

  • style_labels (list) – properties the tuple is meant to describe

Returns:

legend_label – String labeling the group

Return type:

str

Examples

>>> to_legend_label(('Function', True, False), ['label', 'static', 'dynamic'])
'Function, static'
>>> to_legend_label(('Function', False, True), ['label', 'static', 'dynamic'])
'Function, dynamic'

fmdtools.analyze.graph.base

Graphing in fmdtools relies on the Graph class, which can be used to plot different characteristics of graphs using FRDL.

While this is the intent of the graph package, there are some inherent limitations with working with networkx/graphviz, and not all FRDL constructs are representable in fmdtools at present.

See the following examples for “typical” representation of an architecture. In this example, activation arrows were added to the Graph structure, which is possible when working with the base Graph class, but often is not added in ModelGraphs because the information has not been defined in underlying model constructs.

Use-case

FRDL

graphviz

networkx

Decomposition

frdl_dec

gv_dec

nx_dec

Provides representations and visualizations of a model graph structure.

Main user-facing individual graphing classes:

Private Methods:

class fmdtools.analyze.graph.base.Graph(g, check_info=True)

Bases: object

Base class for graphs which can be extended to represent various objects.

Essentially provides a convenience interface for networkx to enable quick visualization and analysis of model properties.

g

Networkx graph to run analyses on.

Type:

nx.Graph

pos

Dict of node positions set using set_pos.

Type:

dict

edge_styles

Dict of styles for each edge set using set_edge_styles.

Type:

dict

node_groups

Dict of node groups by tag with key (tag1, tag2) and value [node1, node2].

Type:

dict

node_styles

Dict of styles for each node set using set_node_styles.

Type:

dict

edge_groups

Dict of edge groups by tag with key (tag1, tag2) and value [edge1, edge2].

Type:

dict

edge_labels

Labels for each edge.

Type:

Labels

node_labels

Labels for each node.

Type:

Labels

Parameters:

g (networkx.Graph) – Graph to analyze.

Examples

>>> from fmdtools.analyze.graph.style import mod_prefix
>>> loc = mod_prefix()
>>> graph = Graph(ex_nxgraph)
>>> graph.set_pos(auto='kamada_kawai')
>>> fig, ax = graph.draw(saveas=loc+'nx_funcdecomp.svg')
>>> graph.set_edge_labels(title="name")
>>> dot = graph.draw_graphviz(disp=False, saveas=loc+'gv_funcdecomp.svg')
add_node_groups(**node_groups)

Create arbitrary groups of nodes to displayed with different styles.

Parameters:

**node_groups (iterable) – nodes in groups. see example.

Examples

>>> graph = Graph(ex_nxgraph)
>>> graph.add_node_groups(group1=('function_a', 'function_b'), group2=('function_c',))
>>> graph.set_node_styles(group={'group1': {'nx_node_color':'green'}, 'group2': {'nx_node_color':'red'}})
>>> fig, ax = graph.draw()

would show two different groups of nodes, one with green nodes, and the other with red nodes

calc_aspl()

Compute average shortest path length of the graph.

Returns:

aspl – Average shortest path length

Return type:

float

calc_modularity()

Compute network modularity of the graph.

Returns:

modularity

Return type:

Modularity

calc_robustness_coefficient(trials=100, seed=False)

Compute robustness coefficient of graph representation of model mdl.

Parameters:
  • trials (int) – number of times to run robustness coefficient algorithm (result is averaged over all trials)

  • seed (int) – optional seed to instantiate test with

Returns:

RC

Return type:

robustness coefficient

check_type_info()

Check that nodes and edges have type data.

draw(figsize=(12, 10), title='', fig=False, ax=False, withlegend=True, legend_bbox=(1, 0.5), legend_loc='center left', legend_labelspacing=2, legend_borderpad=1, saveas='', **kwargs)

Draw a graph with given styles corresponding to the node/edge properties.

Parameters:
  • figsize (tuple, optional) – Size for the figure (plt.figure arg). The default is (12,10).

  • title (str, optional) – Title for the plot. The default is “”.

  • fig (bool, optional) – matplotlib figure to project on (if provided). The default is False.

  • ax (bool, optional) – matplotlib axis to plot on (if provided). The default is False.

  • withlegend (bool, optional) – Whether to include a legend. The default is True.

  • legend_bbox (tuple, optional) – bbox to anchor the legend to. The default is (1,0.5), which places legend on the right.

  • legend_loc (str, optional) – loc argument for plt.legend. The default is “center left”.

  • legend_labelspacing (float, optional) – labelspacing argument for plt.legend. the default is 2.

  • legend_borderpad (str, optional) – borderpad argument for plt.legend. the default is 1.

  • saveas (str, optional) – file to save as (if provided).

  • **kwargs (kwargs) – Arguments for various supporting functions: (set_pos, set_edge_styles, set_edge_labels, set_node_styles, set_node_labels, etc)

Returns:

  • fig (matplotlib figure) – matplotlib figure to draw

  • ax (matplotlib axis) – Ax in the figure

draw_graphviz(disp=True, saveas='', **kwargs)

Draw the graph using pygraphviz for publication-quality figures.

Note that the style may not match one-to-one with the defined none/edge styles.

Parameters:
  • disp (bool) – Whether to display the plot. The default is True.

  • saveas (str) – File to save the plot as. The default is ‘’ (which doesn’t save the plot’).

  • **kwargs (kwargs) – Arguments for various supporting functions: (set_pos, set_edge_styles, set_edge_labels, set_node_styles, set_node_labels, etc) Can also provide kwargs for Digraph() initialization.

Returns:

dot – Graph object corresponding to the figure.

Return type:

PyGraphviz DiGraph

find_bridging_nodes()

Determine bridging nodes in a graph representation of model mdl.

Returns:

bridgingNodes

Return type:

list of bridging nodes

find_high_degree_nodes(p=90)

Determine highest degree nodes, up to percentile p, in graph.

Parameters:

p (int (optional)) – percentile of degrees to return, between 0 and 100

Returns:

highDegreeNodes

Return type:

list of high degree nodes in format (node,degree)

move_nodes(**kwargs)

Set the position of nodes for plots in analyze.graph using a graphical tool.

Note: make sure matplotlib is set to plot in an external window (e.g., using ‘%matplotlib qt)

Parameters:

**kwargs (kwargs) – keyword arguments for graph.draw

Returns:

p – Graph Iterator (in analyze.Graph)

Return type:

GraphIterator

plot_bridging_nodes(title='bridging nodes', node_kwargs={'gv_fillcolor': 'red', 'nx_node_color': 'red'}, **kwargs)

Plot bridging nodes using self.draw().

Parameters:
  • title (str, optional) – Title for the plot. The default is ‘bridging nodes’.

  • node_kwargs (dict, optional) – Non-default fields for NodeStyle

  • **kwargs (kwargs) – kwargs for Graph.draw

Returns:

fig – Figure

Return type:

matplotlib figure

plot_degree_dist()

Plot degree distribution of graph representation of model mdl.

Returns:

fig – plot of distribution

Return type:

matplotlib figure

plot_high_degree_nodes(p=90, title='', node_kwargs={'gv_fillcolor': 'red', 'nx_node_color': 'red'}, **kwargs)

Plot high-degree nodes using self.draw().

Parameters:
  • p (int (optional)) – percentile of degrees to return, between 0 and 100

  • title (str, optional) – Title for the plot. The default is ‘High Degree Nodes’.

  • node_kwargs (dict : kwargs to overwrite the default NodeStyle)

  • **kwargs (kwargs) – kwargs for Graph.draw

Returns:

fig – Figure

Return type:

matplotlib figure

set_edge_labels(title='edgetype', title2='', subtext='states', **edge_label_styles)

Create labels using Labels.from_iterator for the edges in the graph.

Parameters:
  • title (str, optional) – property to get for title text. The default is ‘id’.

  • title2 (str, optional) – property to get for title text after the colon. The default is ‘’.

  • subtext (str, optional) – property to get for the subtext. The default is ‘states’.

  • **edge_label_styles (dict) – LabelStyle arguments to overwrite.

set_edge_styles(edgetype={}, **edge_styles)

Set self.edge_styles and self.edge_groups given the provided edge styles.

Parameters:
  • edgetype (dict, optional) – kwargs to EdgeStyle for the given node type (e.g., containment, etc).

  • **edge_styles (dict, optional) – Dictionary of tags, labels, and styles for the edges that overwrite the default. Has structure {tag:{label:kwargs}}, where kwargs are the keyword arguments to nx.draw_networkx_edges. The default is {“label”:{}}.

set_heatmap(heatmap, cmap=<matplotlib.colors.LinearSegmentedColormap object>, default_color_val=0.0, vmin=None, vmax=None)

Set the association and plotting of a heatmap on a graph.

Parameters:
  • heatmap (dict/result) – dict/result with keys corresponding to the nodes and values in the range of a heatmap (0-1)

  • cmap (mpl.Colormap, optional) – Colormap to use for the heatmap. The default is plt.cm.coolwarm.

  • default_color_val (float, optional) – Value to use if a node is not in the heatmap dict. The default is 0.0.

  • vmin (float) – Minimum value for the heatmap. Default is None, which sets it to the minimum value of the heatmap.

  • vmax (float) – Maximum value for the heatmap. Default is None, which sets it to the maximum value of the heatmap.

Examples

The below should draw function a red, function b blue, function c pink, and all else grey: >>> graph = Graph(ex_nxgraph) >>> graph.set_heatmap({‘function_a’: 1.0, ‘function_b’: 0.0, ‘function_c’: 0.75}, default_color_val=0.5) >>> fig, ax = graph.draw()

set_node_labels(title='shortname', title2='', subtext='', **node_label_styles)

Create labels using Labels.from_iterator for the nodes in the graph.

Parameters:
  • title (str, optional) – Property to get for title text. The default is ‘id’.

  • title2 (str, optional) – Property to get for title text after the colon. The default is ‘’.

  • subtext (str, optional) – property to get for the subtext. The default is ‘’.

  • node_label_styles (dict) – LabelStyle arguments to overwrite.

set_node_styles(nodetype={}, **node_styles)

Set self.node_styles and self.edge_groups given the provided node styles.

Parameters:
  • nodetype (dict, optional) – kwargs to NodeStyle for the given node type (e.g., Block, Flow, etc).

  • **node_styles (dict, optional) – Dictionary of tags, labels, and style kwargs for the nodes that overwrite the default. Has structure {tag:{label:kwargs}}, where kwargs are the keyword arguments to nx.draw_networkx_nodes. The default is {“label”:{}}.

set_pos(auto=True, overwrite=True, **pos)

Set graph positions to given positions, (automatically or manually).

Parameters:
  • auto (str, optional) – Whether to auto-layout the node position. The default is True. If a string is provided, calls method_layout, where method is the string provided

  • overwrite (bool, optional) – Whether to overwrite the existing pos. Default is True.

  • **pos (nodename=(x,y)) – Positions of nodes to set. Otherwise updates to the auto-layout or (0.5,0.5)

set_properties(**kwargs)

Set properties using kwargs where there is a given set_kwarg command.

sff_model(endtime=5, pi=0.1, pr=0.1, num_trials=100, start_node='random', error_bar_option='off')

Susceptible-fix-fail model.

Parameters:
  • endtime (int) – simulation end time

  • pi (float) – infection (failure spread) rate

  • pr (float) – recovery (fix) rate

  • num_trials (int) – number of times to run the epidemic model, default is 100

  • error_bar_option (str) – option for plotting error bars (first to third quartile), default is off

  • start_node (str) – start node to use in the trial. default is ‘random’

Returns:

fig

Return type:

plot of susc, fail, and fix nodes over time

class fmdtools.analyze.graph.base.GraphInteractor(g_obj, **kwargs)

Bases: object

A simple interactive graph for consistent node placement, etc.

Used in set_pos to set node positions.

epsilon = 0.2
get_closest_point(event)

Find the closest node to the given click to see if it should be move.

on_button_press(event)

Determine what to do when a button is pressed.

on_button_release(event)

Determine what to do when the mouse is released.

on_mouse_move(event)

Change the node position when the user drags it.

print_pos()

Print the current node positions in the graph from the console.

refresh_plot()

Refresh the plot with the new positions.

showverts = True
fmdtools.analyze.graph.base.data_average(data)

Average each column in data.

fmdtools.analyze.graph.base.data_error(data, average)

Calculate error for each column in data.

Parameters:
  • data (list) – List of lists from sff_model

  • average (list) – Average of data generated from sff_model over time

Returns:

  • lower_error (float) – Lower bound of error

  • upper_error (float) – Upper bound of error

fmdtools.analyze.graph.base.get_group_kwarg(group_dict, group_membership)

Get the kwargs related to group membership for a node/edge style.

fmdtools.analyze.graph.base.get_label_groups(iterator, *tags)

Create groups of nodes/edges in terms of discrete values for the given tags.

Parameters:
  • iterator (iterable) – e.g., nx.graph.nodes(), nx.graph.edges()

  • *tags (list) – Tags to find in the graph object (e.g., label, status, etc.)

Returns:

label_groups

Dict of groups of nodes/edges with given tag values. With structure::

{(tagval1, tagval2…):[list_of_nodes]}

Return type:

dict

fmdtools.analyze.graph.base.sff_one_trial(start_node_selected, g, endtime=5, pi=0.1, pr=0.1)

Calculate one trial of the sff model.

Parameters:
  • start_node_selected (str) – node to start the trial from

  • g (networkx graph) – graph to run the trial over

  • endtime (int) – simulation end time

  • pi (float) – infection (failure spread) rate

  • pr (float) – recovery (fix) rate

fmdtools.analyze.graph.model

Module for generating graphs from models.

Provides classes:

  • ModelGraph: Superclass for graphs generated from modelling constructs.

  • ExtModelGraph: ModelGraph class that can be extended w- custom inits.

and methods:

  • add_node(): Add node to a graph for a given object.

  • add_edge(): Add an edge from a base object to another object.

  • set_node_states(): Set node states from an object.

  • add_meth_edge(): Addes edges from methods to their objects.

  • remove_base(): Remove the root note of a graph.

  • graph_factory(): Creates the default Graph for a given object.

class fmdtools.analyze.graph.model.ExtModelGraph(mdl, get_states=True, time=0.0, check_info=False, **kwargs)

Bases: ModelGraph

Extensible ModelGraph which separates graph generation from state setting.

To make a ModelGraph for a particular object, one needs to create two methods for the class:

  • nx_from_obj, which returns a networkx graph with ‘edgetype’ and ‘nodetype’

information, and - set_nx_states, which attaches state information such as states and modes to node/edge attributes.

nx_from_obj(mdl, **kwargs)

Alias for nx_from_obj, the method used to instantiate the graph.

set_nx_states(mdl, **kwargs)

Alias for set_nx_states, which is used to map model states to graph attr.

class fmdtools.analyze.graph.model.ModelGraph(mdl, check_info=True, **kwargs)

Bases: Graph

Superclass for Graphs meant to represent specific model constructs.

Specifically, ModelGraphs have node/edge properties like “state” and “mode” corresponding to an external model simulation.

Parameters:
  • get_states (bool) – whether to get states for the graph

  • **kwargs – keyword arguments for self.nx_from_obj

Examples

>>> from fmdtools.define.block.function import ExampleFunction
>>> mg = ModelGraph(ExampleFunction())
>>> mg.get_nodes()
['examplefunction', 'examplefunction.m', 'examplefunction.p', 'examplefunction.s', 'examplefunction.sp', 'examplefunction.t', 'examplefunction.exampleflow', 'examplefunction.dynamic_behavior']
animate(history, times='all', figsize=(6, 4), **kwargs)

Successively animate a plot using Graph.draw_from.

Parameters:
  • history (History) – History with faulty and nominal states

  • times (list, optional) – List of times to animate over. The default is ‘all’

  • figsize (tuple, optional) – Size for the figure. The default is (6,4)

  • **kwargs (kwargs)

Returns:

ani – Animation object with the given frames

Return type:

matplotlib.animation.FuncAnimation

draw_from(time, history=, rem_ind=0, **kwargs)

Draws the graph with degraded/fault data at a given time.

Parameters:
  • time (int) – Time to draw the graph (in the history)

  • history (History, optional) – History with nominal and faulty history. The default is History().

  • **kwargs (**kwargs) – arguments for Graph.draw

Returns:

  • fig (matplotlib figure) – matplotlib figure to draw

  • ax (matplotlib axis) – Ax in the figure

draw_graphviz_from(time, history=, **kwargs)

Draws the graph with degraded/fault data at a given time.

Parameters:
  • time (int) – Time to draw the graph (in the history)

  • history (History, optional) – History with nominal and faulty history. The default is History().

  • **kwargs (**kwargs) – arguments for Graph.draw

Returns:

dot – Graph drawn with attributes at the given time.

Return type:

graphvis graph

get_nodes(rem_ind=0)

Get nodes (with shortened names if needed).

set_degraded(other)

Set ‘degraded’ state in networkx graph.

Uses difference between states with another Graph object.

Parameters:

other (Graph) – (assumed nominal) Graph to compare to

set_from(time, history=, rem_ind=0)

Set ModelGraph faulty/degraded attributes from a given history.

set_resgraph(other=False)

Process results for results graphs (show faults and degradations).

Parameters:

other (Graph, optional) – Graph to compare with (for degradations). The default is False.

fmdtools.analyze.graph.model.add_edge(g, basename, name, rolename, edgetype)

Add an edge from a base object to another object.

Parameters:
  • g (nx.Graph) – Networkx graph to add to.

  • baseobj (object) – Object that the object is within.

  • basename (str) – Name of the base object.

  • roleobj (object) – Object to add.

  • rolename (str) – Name of the object in the context of the base object.

fmdtools.analyze.graph.model.add_meth_edge(g, obj, rolename='action', edgetype='activation')

If the object is a method, attaches an edge to the containing object.

Parameters:
  • g (nx.Graph) – Networkx graph to add to.

  • obj (object) – Object to check.

  • objname (str) – Name of the object.

fmdtools.analyze.graph.model.add_node(obj, g=None, name='', classname='', nodetype='', get_attrs=False, get_source=False, get_states=False, time=None, **kwargs)

Add a node to a graph for a given object.

Parameters:
  • g (nx.Graph) – Networkx graph to add to.

  • obj (object) – Object to add to the graph.

  • rolename (str, optional) – role of the graph in the larger system (if not base). The default is ‘base’.

fmdtools.analyze.graph.model.create_inheritance_subgraph(obj, g=None, name='', end_at_fmdtools=True)

Create a graph of the inheritance of a given object from fmdtools classes.

Parameters:
  • obj (Object) – Object.

  • g (graph, optional) – Networkx graph to add to. The default is None.

  • end_at_fmdtools (bool) – Option to end at first fmdtools node while building the subgraph Default is True, which stops the subgraph at the first fmdtools class, rather than includeing the fmdtools class inheritance.

Returns:

g – Networkx graph of inheritance from classes.

Return type:

graph

Example

>>> from fmdtools.define.block.function import ExampleFunction
>>> g = create_inheritance_subgraph(ExampleFunction(), end_at_fmdtools=False)
>>> [*g.nodes]
['examplefunction', 'fmdtools.define.block.function.ExampleFunction', 'fmdtools.define.block.function.Function', 'fmdtools.define.block.base.Block', 'fmdtools.define.block.base.Simulable', 'fmdtools.define.object.base.BaseObject']
>>> [*g.edges]
[('examplefunction', 'fmdtools.define.block.function.ExampleFunction'), ('fmdtools.define.block.function.ExampleFunction', 'fmdtools.define.block.function.Function'), ('fmdtools.define.block.function.Function', 'fmdtools.define.block.base.Block'), ('fmdtools.define.block.base.Block', 'fmdtools.define.block.base.Simulable'), ('fmdtools.define.block.base.Simulable', 'fmdtools.define.object.base.BaseObject')]
fmdtools.analyze.graph.model.remove_base(g, basename)

Remove base node to enable flat view of model graph.

fmdtools.analyze.graph.model.set_node_states(g, obj, name, time=None)

Attach stateful attributes to the given node.

Used to determine faults and degradations in scenario visualization.

Parameters:
  • g (nx.Graph) – Networkx graph to add to.

  • obj (object) – Object to get the states from.

  • rolename (str) – Name of the object in the larger system (if the node is not a BaseObject).

  • time (float, optional) – Time to get the states from. The default is None.