Graph / subgraph attributes

I’m playing a bit with the Graphviz grammar, and there are a few things that puzzle me.

First: subgraph attributes. The following is valid:

graph {
  subgraph {}[color=red]
}

But evaluating it (or variations with nested nodes and edges) through the canon output format will simply remove [color=red]. My assumption is that the syntax is legal (because it makes the parser easier) but this kind of attributes on a subgraph are ignored. Is that correct?

My second question is about graph attributes.
The following graph:

graph {
  node[color=red]
  a
}

Will have, more or less, a canonical output of:

graph {
  a[color=red]
}

But the following graph:

graph {
  graph[bgcolor=red]
}

Does not change when “canonized”.

Is there a particular reason for this apparently inconsistent behaviour? I think there might be something subtle I’m missing, the distinction between graphs and subgraphs, and the way they are handled, always seems to elude me.

[I am not a Graphviz developer, just a groupie]

  • Graphviz allows one to write many legal-but-head-scratching statements
  • Note that color=red only applies to nodes, clusters, and edges.
  • Graphviz is more casual about punctuation than most languages. Nothing too magic about newlines
  • I think what you effectively wrote was:
graph {
  subgraph {}  // subgraph commands are terminated by }
  [color=red]    // does not apply to graphs, so applies to nothing at all, a legal noop
}

As to your graphs-vs-nodes question, the two results are different but equivalent.
Finally, graphs, subgraphs, and clusters are (sometimes confusing) variations on a theme. Until someone produces a giant table describing all the similarities and differences, I suggest attacking the question piecemeal. Pose questions about specific features/problems.

Thanks for taking the time to answer!

I have concrete reasons to believe that my [color=red] is considered to apply to the subgraph statement.

First, the following fails to be processed:

graph {
  [color=red]
}

Which seems to imply that you can’t really have a list of attributes that apply to nothing.

Second, if I understand the parser’s code properly, it explicitly supports graph[attributes]. This is born out by the language specifications, although these do not appear to be up to date.

This second reason is the one that bothers me: this doesn’t appear to be an accident but something that’s explicitly supported by the language, and I don’t understand what it does!

Oh, and it seems I was completely mistaken about the second part of my question - I don’t know why I thought the node[color=red] statements were merged into every node in the canonical form, but I just checked again and they do not. So, no inconsistency there, sorry for the misreport!

Speaking from the perspective of the person that wrote it, I’d say the best thing is to read cgraph/grammar.y and possibly suggest improvements (that don’t break anything that already works). No one poked around in these corners very much.

I’d be happy to, if this was in a language that I could program in. Unfortunately…

As the author of this code, could you explain how graphviz uses attributes set on a graph element? I specifically mean in that part of the grammar:

attr_stmt : ( `graph` | `node` | `edge` ) attr_list

I understand node and edge, but I’m not sure what graph does.

I suppose I should have phrased my question that way from the beginning…

It sets graph specific attributes on a graph, e.g. bgcolor as in this example.

You can also omit the graph keyword and the brackets and specify the same attribute directly as in this example.

Graph specific attributes are indicated with a G in the Used By column in the table in the Node, Edge and Graph Attributes documentation.