Node layering in Graphviz - graph

I'm creating a graph using Graphviz (compiled with neato). This graph contains many overlapping nodes which is perfectly fine. However, there is a group of large nodes which I prefer to always be on top of other small nodes - even-though I prefer to define the large nodes first in the graph (which makes them get painted at the very bottom).
Any way I can force this?
Edit:
Here's a small example, just to clarify what I mean:
graph G {
node [style=filled,fillcolor=black];
BigNode [fillcolor=skyblue,shape=Msquare];
node [style=filled,fillcolor=red,shape=circle];
edge [style=invis]
1 -- BigNode[len=0.5];
2 -- BigNode[len=1];
}
I'd like for BigNode to be painted over node 1.

I did find one (sort of) solution...
I found that if you postpone only the node definition to the end, even if you defined edges for this node earlier, it will be painted top-most.
I realize this contradicts what I defined earlier, but this was the only possible solution in this case and it was the one I eventually had to use.
In my short example, you would do this:
graph G {
node[style=filled,fillcolor=black];
// Definition of BigNode moved to the end of the file
/*BigNode [fillcolor=skyblue,shape=Msquare];*/
node[style=filled,fillcolor=red,shape=circle];
edge[style=invis]
1 -- BigNode[len=0.5];
2 -- BigNode[len=1];
// Defined after already defining edges for BigNode
BigNode [fillcolor=skyblue,shape=Msquare];
}
In the resulting graph, BigNode is painted over node 1

I don't think it's possible. The official neato guide talks about node layering on pages 6 through 9. It looks like the most you can do is adjust the length of edges and pin down nodes: you can't actually control how nodes layer over each other.

Related

Creating a network graph with set node positions and concentrated edges with both circleheads and arrowheads in R

I've been trying to find a way to replicate the following network graph format in R using DiagrammeR/GraphViz, but without success (ignore the thick black arrow on N1): https://i.stack.imgur.com/oHpQz.png
The graph is a directed graph and each edge in a certain direction either ends with an arrowhead (-->) if the edge value is positive, or a circle/odot (--o) if the edge value is negative. Between a pair of nodes (ex. N1 -- A1), there can be an edge N1 --> A1 and an edge A1 --o N1, and these need to be concentrated so that the two edges look like one line with an arrowhead on one end and a circlehead on the opposite end (like this: o--->). These cannot be parallel or look like two edges ideally.
Another requirement is that the nodes have to be in very specific positions and remain there throughout model simulations where edges might change. From what I have tried and the documentation I have read, this is not possible to do in DOT format, but is possible in neato format.
This is where I get a problem. In neato, I can align the nodes exactly where I want them by defining their x,y positions. However, when I use concentrate = true to create the o---> edge from two otherwise parallel edges, only one type of arrowhead remains. So an edge that's supposed to look like o---> ends up looking like ---> or o---.
This is not a problem in DOT format as concentrate = true does what I want it to do, but in DOT I cannot assign exact node positions. I have tried getting around this using node ranks but without much luck. It seems to stack nodes I want in different ranks within the same rank. As well, concentrate = true doesn't seem to work for edges between nodes within the same rank, as it leaves them as two separate curved edges ---> and o--- without concentrating them.
The reason why I need this to work is because I'm running model simulations where the edges change, and I need to generate hundreds of such graphs. For easy comparison, the nodes need to stay in the same place for consistency.
This is the closest I could come up with using neato format (nodes are positioned the way I want but it's not showing the proper o---> for all the black edges minus self-edges; red edges are true one-way links): https://i.stack.imgur.com/YJBY7.jpg
If only the edges showed up as the proper o---> format, this would be perfect for my needs. If you know of any way to fix this issue using DiagrammeR/GraphViz, or even another program, I would be so grateful. Thanks!
You probably don't need concentrate. Look at arrowtail and dir (https://www.graphviz.org/doc/info/attrs.html#d:arrowtail and https://www.graphviz.org/doc/info/attrs.html#d:dir) and neato -n
digraph c {
graph[label="can neato do the work?"]
node[shape=circle]
a [pos="100,100"]
b [pos="200,100"]
c [pos="300,100"]
a->b [dir=both arrowtail=odot]
c->c [dir=both arrowtail=odot arrowhead=none]
}
Giving:

Convert a map with houses into a graph

I am curious how map software (Google/Bing maps) convert a map into a graph in the backend.
Now if we add houses between intersections 1 and 2, then how would the graph change. How do map software keep track of where the houses are?
Do they index the intersection nodes and also have smaller "subnodes" (between 1 and 2 in this case)? Or do they do this by having multiple layers? So when a user enters a home number, it looks up where the home is (i.e. between which vertices the home is located). After that, they simply apply a shortest path algorithm between those two node and at the beginning and the end, they basically make the home node go to one of the main vertices.
Could someone please give me a detailed explanation of how this works? Ultimately I would like to understand how the shortest path is determined given two the "address" of two "homes" (or "subnodes").
I can only speak for GraphHopper, not for the closed source services you mentioned ;)
GraphHopper has nodes (junctions) and edges (connection between those junctions), nearly exactly how your sketch looks like. This is very fast for the routing algorithms as it avoids massive traversal overhead of subnodes. E.g. in an early version we used subnodes everytime the connection was not straight (e.g. curved street) and this was 8 times slower and so we avoided those 'pillar' nodes and only used the 'tower' nodes for routing.
Still you have to deal with two problems:
How to deal with queries starting on the edge at e.g. house number 1? This is solved via introducing virtual nodes for every query (which can contain multiple locations), and you also need the additional virtual edges and hide some real edges. In GraphHopper we create a lightweight wrapper graph around the original graph (called QueryGraph) which handles all this. It then behaves exactly like a normal 'Graph' for every 'RoutingAlgorithm' like Dijkstra or A*. Also it becomes a bit hairy when you have multiple query locations on one edge, e.g. for a route with multiple via points. But I hope you get the main idea. Another idea would be to do the routing for two sources and two targets but initialized with the actual distance not with 0 like it is normally done for the first nodes. But this makes the routing algorithms more complex I guess.
And as already stated, most of the connections between junctions are not straight and you'll have to store this geometry somewhere and use it to draw the route but also to 'snap a location to the closest road' do finally do the actual routing. See LocationIndexTree for code.
Regarding the directed graphs. GraphHopper stores the graph via undirected edges, to handle oneways it stores the access properties for every edge and for every vehicle separately. So we avoid storing two directed edges and all of its properties (name/geometry/..), and make the use case possible "oneway for car and twoway for bike" etc. It additionally allows to traverse an edge in the reverse direction which is important for some algorithms and e.g. the bidirectional Dijkstra. This would not be possible if the graph would be used to model the access property.
Regarding 'nearly exactly how your sketch looks like': node 1, 3, 7 and 8 would not exist as they are 'pillar' nodes. Instead they would only 'exist' in the geometry of the edge.
To represent the connectivity of a road network, you want your directed road segments to be the graph nodes and your intersections to be collections of directed edges. There is a directed edge from X to Y if you can drive along X and then turn onto or continue on Y.
Consider the following example.
a====b====c
|
| <--one way street, down
|
d
An example connectivity graph for this picture follows.
Nodes
ab
ba
bc
cb
bd
Edges
ab -> bc
ab -> bd
cb -> ba
cb -> bd
Note that this encodes the following information:
No U-turns are allowed at the intersection,
because the edges ab -> ba and cb -> bc are omitted.
When coming from the right a left turn onto the vertical road is allowed,
because the edge cb -> bd is included.
With this representation, each node (directed road segment) has as an attribute all of the addresses along its span, each marked at some distance along the directed road segment.

Graphviz splines=false has no effect on undirected graph with bi-directional a -- b/b -- a edges

I am drawing an undirected graph with Graphviz that has redundant edges, (e.g. A -- B and B -- A). I would like to see only one line between the two vertices, regardless of whether there is a redundant reverse edge in the data. My question is, is there a way to do this with Graphviz, without having to use some other tool/code first to remove the redundant edges? I have tried graph [splines=false]; without any success. Below is a minimal example:
graph G {
graph [splines=false];
node [shape=point];
a -- b;
b -- a;
}
And the output:
What I want as output is:
despite the redundant edges that may exist in the specified graph.
You may try setting nodesep to 0 :
... this affects the spacing between loops on a single node, or multiedges between a pair of nodes.
Not sure if nodesep is completely set to 0, because in the documentation the minimum value indicated is 0.02. A quick test seems to be ok, though.
Try "strict graph G { ... }"
A strict graph or digraph disallows parallel edges.
Stephen North north#graphviz.org

Plotting nodes on a graph based on node-pair distances

I was wondering if someone could help with the following problem.
I have a dozen nodes, each a different sized circle between 0 - 10. I have a distance for each node-pair (e.g. node A and B are 6 from each other, etc.)
Given this data, would it be possible to compute the position of each node on a grid?
The distance could be from the centre or the edge of a node.
Thanks.
If you just want to have a graph to look at, try building a neato file where you specify edge distance. Neato is a layout program that is part of the GraphViz package.
This is quite easy. Your example above would look like this:
graph G {
A -- B [len=6]
}

How can you describe this kind of graph?

I know for sure that this is a simple directed graph. But I cannot say that this is a ring graph/network, because node 3 has a degree of 4. But as I imagine this, you cannot go to node 7 from node 3 if the preceding node is node 2, and you cannot go to node 4 from node 3 if the preceding node is node 6. That means the only way to traverse this graph is to start from one node and then go to the adjacent node that has a number greater than the current node (except for node 7 to node 1). What kind of graph is this? Thanks in advance!
http://img231.imageshack.us/img231/5492/graphl.jpg
Yes, it is a simple directed graph. It is also an Eulerian graph with exactly one Eulerian circuit. That's probably its most interesting property.
You could redraw the graph as a standard Eulerian Graph without the addition rules by dividing node 3 into two nodes, node 3 and node 6A, where 2-3-4 and 6-6A-7 are the only valid paths through the two nodes. At this point the graph would look like a figure eight. The nodes could then be rearranged in a circle while maintaining the topology.

Resources