it has 2 functions:

  • build flowchart - takes argument of theme, sets dot = Digraph() and specifies all bits
  • create flowcharts - creates 2 files one with _light at the end. specifies png

from graphviz import Digraph

def build_flowchart(theme="dark"):
    dot = Digraph()

    if theme == "dark":
        dot.attr(bgcolor="#1e1e1e")
        node_fill = "#2d2d2d"
        font_color = "white"
        edge_color = "white"
    else:  # light theme
        dot.attr(bgcolor="white")
        node_fill = "#f5f5f5"
        font_color = "black"
        edge_color = "black"

    # Default node styling
    dot.attr('node',
             style='filled',
             fillcolor=node_fill,
             fontcolor=font_color,
             color=edge_color)

    # Default edge styling
    dot.attr('edge',
             color=edge_color,
             fontcolor=edge_color)


    with dot.subgraph() as s:
        s.attr(rank='same')
        s.node('question', 'Is PCA stress testing\ntheoretically sound?',shape='diamond', fillcolor='yellow', fontcolor='red')
        s.node('industrypractice', 'Industry Practice')



    # Principal Components
    #dot.node('industrypractice', 'Industry Practice')
    dot.node('pcabasedstresstesting', 'PCA based stressed testing')
    dot.node('theoreticalinconsistencies', 'Theoretcial Inconsistencies')
    dot.node('pcs', 'Principal Components')
    dot.node('pcsindependent', 'PCs Assumed Independent')
    dot.node('stresses', 'stresses')
    dot.node('isolation', 'isolation')
    dot.node('combined', 'combined')
    dot.node('determined', 'determined by classical pca')
    dot.node('validity','validity')
    dot.node('decomp','decomposition stable = orthogonality holds out of sample')
    dot.node('reinter','output reinterpreted')
    dot.node('classuncorr','classical pca ensures uncorrelated only')
    dot.node('model','modelling of scores')
    #dot.node('question', 'Is PCA stress testing\ntheoretically sound?', shape='diamond', fillcolor='yellow', fontcolor='red')




    dot.edge('question', 'industrypractice')
    dot.edge('pcs','model')
    dot.edge('determined','classuncorr')
    dot.edge('pcsindependent','classuncorr')
    dot.edge('industrypractice', 'pcabasedstresstesting')
    dot.edge('pcs', 'pcsindependent')
    dot.edge('pcs', 'determined')
    dot.edge('determined','reinter')
    dot.edge('pcabasedstresstesting', 'pcs')
    dot.edge('pcabasedstresstesting', 'theoreticalinconsistencies')
    dot.edge('theoreticalinconsistencies','pcsindependent')
    dot.edge('pcs','stresses')
    dot.edge('stresses','validity')
    dot.edge('validity','decomp')
    dot.edge('stresses','isolation')
    dot.edge('stresses','combined')
    return dot


def create_flowcharts(filename='flowchart', file_format='png'):
    # Dark version (original)
    dark = build_flowchart(theme="dark")
    dark.render(filename, format=file_format, cleanup=True)

    # Light version
    light = build_flowchart(theme="light")
    light.render(f"{filename}_light", format=file_format, cleanup=True)



This site uses Just the Docs, a documentation theme for Jekyll.