graphviz

How to position the legend at the bottom-left of the graph in a Graphviz flowchart?


I'm working on a flowchart using Graphviz and need to position the legend at the bottom-left of the graph. Below is the code I am currently using, where I have added a subgraph for the legend. By default, the legend is placed at the top, but I would like to move it to the bottom-left.

Here’s a simplified version of my code:

enter image description here

digraph flowchart {
  
  # Graph
  graph [
    overlap = true
    fontsize = 10
  ]
  
  # Define styles for Datasets and Analyses
  node [fontname = 'Calibri Light', fontcolor = white, style = filled]
  
  # Datasets (boxes)
  node [shape = box, fillcolor = firebrick3]  # Set dataset style
  A
  B
  
  # Analyses (circles)
  node [shape = circle, fixedsize = true, width = .9, fillcolor = steelblue3]
  C
  D
  
  # Edges
  {A B}->C
  A->D
  
  # Subgraph for legend
  subgraph cluster_legend {
    graph [
      label = 'Legend'
      labelloc = 't'
      labeljust= 'l'
      fontname = 'Calibri Light'
      color = lightgrey
    ]
    
    # Global node style
    node [fontsize = 9]
    
    # Legend entry for Analysis
    node [shape = circle, fixedsize = true, fillcolor = steelblue3, width = .5, height = .3]
    legend_analysis [label = 'Analysis']
    
    # Legend entry for Data
    node [shape = box, fillcolor = firebrick3, width = .5, height = .5]
    legend_data [label = 'Data']
    
    # Make legend items horizontal
    {rank = same; legend_data; legend_analysis}
  }
}

Could anyone suggest how I can move the legend to the bottom-left of the graph?


Solution

  • Here is one way.

    Kind of convoluted, but this way you don't need invisible nodes/edges to try to coerce the Legend into the desired position.

    /*******************************************************************
      create a second graph containing the legend
      use gvpack to combine the two,
      then neato -n2 to create image
    ********************************************************************/
    digraph flowchart {
      subgraph cluster_main {  //  sometimes helps w/ gvpack
      # Graph
      graph [
        //  overlap = true  //  dot ignores overlap
        fontsize = 10
      ]
      
      # Define styles for Datasets and Analyses
      node [fontname = "Calibri Light", fontcolor = white, style = filled]
      
      # Datasets (boxes)
      node [shape = box, fillcolor = firebrick3]  # Set dataset style
      A
      B
      
      # Analyses (circles)
      node [shape = circle, fixedsize = true, width = .9, fillcolor = steelblue3]
      C
      D
      
      # Edges
      {A B}->C
      A->D
      }
    }
    /**  now the legend  **/
    digraph L {
     # Subgraph for legend
      subgraph cluster_legend {
        graph [
          label = "Legend"
          labelloc = "t"
          labeljust= "l"
          fontname = "Calibri Light"
          color = lightgrey
        ]
        
        # Global node style
        node [fontsize = 9]
        
        # Legend entry for Analysis
        node [shape = circle, fixedsize = true, fillcolor = steelblue3, width = .5, height = .3]
        legend_analysis [label = "Analysis"]
        
        # Legend entry for Data
        node [shape = box, fillcolor = firebrick3, width = .5, height = .5]
        legend_data [label = "Data"]
        
        # Make legend items horizontal
        {rank = same; legend_data; legend_analysis}
      }
    }
    

    And command line (note dot output format is xdot):

    dot myFile.gv | gvpack -array_il1 |neato -n2 -T...
    

    Giving:
    enter image description here