I have perfection paralysis when it comes to producing something graphic. If symmetries of the visual have not been fully explored, I have a harder time comprehending what is going on. I am a very visual learner as well, and I LOVE to simplify things that I just learned and draw them on paper.
Graphviz is a nice tool to draw thing automatically, but it could be better. Let's start with an example of a good graph )a state machine rather). Never mind the quality (it can be redrawn with a better tool) this one is almost perfect, except that I would turn it counter-clockwise 45 degrees to make the symmetry apparent. It should then take the reader less time to figure out how the states q1 and q2 are similar and how where they differ. I argue that there is a single best way to represent that diagram, given that there are no other pieces of graphic next to it.
(source: gallery.hd.org)
Now let's look at a less than perfect depiction:
(source: softpedia.com)
This looks like something a graphviz would generate. Yes, the edges are smooth but GAAAAWWWD this is unnecessary confusing! It looks like a mind map, not a finished diagram ready for consumption. I believe that human eyes CRAVE (no less) symmetry. Yes, hierarchy, etc. are also important factors.
I am surprised that there aren't better algorithms available. Some people are not visual learners at all; they can grasp abstract concepts by reading symbols. Not me!
So, what is my question? Well, is there better free software available for drawing small-to-medium graphs? Perhaps
Thank you!
Let me know how I can improve this post.
P.S. I took 10 minutes to draw out a similar enough clone in dia. It is still not perfect, but it was convenient to make because everything snaps to grid (and I missed a few little details but do not feel like re-uploading). The LR_0 needs a "Start--->" coming from above to let the user grasp the starting state sooner.
After several attempts at drawing your graph and failing to get a layout that you deem "best", you posed the question here: is there "[b]etter free software [for] drawing small-to-medium graphs." The sole criterion you've given for evaluating layout algorithms is how closely they come to the "[s]ingle best way to represent that diagram." "Best" of course, left for you to decide.
This is more or less the same as attempting to solve a problem using a given programming language, failing, and then asking for a better programming language.
At the heart of graph drawing algorithms are optimization routines that generate then evaluation solutions ('solution' here refers to the coordinates for each node which together comprise a layout). Those solutions are evaluated according to minimization of a single criterion or a series of ranked criteria--i.e., the minimization of one or more attributes of the graph--for instance, the total number of edges that cross, or the sum of the distances between nodes (or the combination of both, or some weighted combination of those two), or the closeness to a symmetrical configuration. Graphviz is comprised of six different layout algorithms (dot neato, fdp, sfdp, twopi, and circo). Of these, it appears you only used dot; however, twopi and circo might have been better options given their strict symmetry constraints which appear to match your own idea of a correctly drawn graph.
Second, the text of your question is directed to "graphs" and graph-drawing, After reading your full description, i don't think your question has anything to do with either concept.
Beyond the general graph drawing algorithms (like graphviz), there are a number of domain-specific layout algorithms, for instance, Hasse diagrams (to represent partially ordered sets in order theory), Barabasi-Albert graphs (scale-free networks), and Erdos-Renyi (random graphs). Each of those algorithms produces a graph layout based on criteria and constraints supplied by the domain--this ought to indicate to you that there is not a single "best" layout across all domains. Although you used the term "graph" in your question, your description indicates that your problem relates to drawing state machines--a highly idiosyncratic type of graph. General graph drawing algorithms are often poor at drawing specialized graphs of this sort because the algorithm knows nothing about domain. In fact, I'm not aware of any layout algorithm for state diagrams--just like there isn't one for flow diagrams (not the same, but similar). Workflow-wise, you might draw the graph in graphviz then import it to Omnigraffle for fine tuning--in Omnigraffle, you'll have fine-grained control over the node and edge placements.
Some softwares let users tweaking layout algorithms in real-time, as long as moving nodes with the mouse. This approach may greatly help you for larger graphs.
I mostly know Gephi (disclamer: I'm a dev).
There are a number of options i know of:
Prefuse - They have an older Java version. The newest version is in Flash and has some nice layouts. Its called Prefuse Flare. The demo page illustrates some of its layout capabilities.
JUNG includes a number of layout options, as well as its powerful graph analysis functions. There are some examples here.
Networkx also includes numerous layout capabilities. Some of them are listed here.
TikZ generates beautiful graph layouts. You can use a manual layout that lets you specify the minimum of hints, or you can ask for automatic layout. Defaults are good, and hooks exist to tweak to perfection.
With the semi-manual layout you don't have to declare every detail, because you can
declare nodes as being 'above of', 'below right of', etc. relative to other nodes.
place your nodes on a raster by entering them as a matrix: very convenient if you want to leave some positions empty.
easily specify in what direction edges should enter, leave, bend, or take corners
For automatic layout, TikZ's graphdrawing library has some pretty slick algorithms.
Here is an example of manual layout and the TeX code used to obtain it:
\usepackage{pgf}
\usepackage{tikz}
\usetikzlibrary{arrows,automata}
\usepackage[latin1]{inputenc}
\begin{document}
\begin{tikzpicture}[->,>=stealth',shorten >=1pt,auto,node distance=2.8cm,
semithick]
\tikzstyle{every state}=[fill=red,draw=none,text=white]
\node[initial,state] (A) {$q_a$};
\node[state] (B) [above right of=A] {$q_b$};
\node[state] (D) [below right of=A] {$q_d$};
\node[state] (C) [below right of=B] {$q_c$};
\node[state] (E) [below of=D] {$q_e$};
\path (A) edge node {0,1,L} (B)
edge node {1,1,R} (C)
(B) edge [loop above] node {1,1,L} (B)
edge node {0,1,L} (C)
(C) edge node {0,1,L} (D)
edge [bend left] node {1,0,R} (E)
(D) edge [loop below] node {1,1,R} (D)
edge node {0,1,R} (A)
(E) edge [bend left] node {1,0,R} (A);
\end{tikzpicture}
\end{document}
Graphviz can generate that diagram you specified.
Image:
Script:
digraph {
ranksep=1;
nodesep=0.5;
node [shape=circle]
Start [margin=0 width=0 shape=plaintext]
q0 [shape = doublecircle label=<<I>q</I><SUB>0</SUB>>]
q1 [label=<<I>q</I><SUB>1</SUB>>]
q2 [label=<<I>q</I><SUB>2</SUB>>]
q3 [label=<<I>q</I><SUB>3</SUB>>]
Start -> q0
q1 -> q0 [xlabel="1"]
q0 -> q1 [xlabel="0"]
q1 -> q3 [label=" 0"]
q3:se -> q3:e [label=" 0,1"]
q2 -> q0 [xlabel="0 "]
q0 -> q2 [xlabel="1 "]
q2 -> q3 [label="1"]
{rank=same; Start; q0; q1}
{rank=same; q2; q3}
}
Source answer
Related
I have a directed graph on 31 nodes for which Graphviz' dot layout engine produces the following layout:
I'm unhappy with the layout because there is too much space surrounding the four-node-cluster 8-10-20-21. What settings can I tweak to improve Graphviz' layout of graphs like these? Interestingly, if I change the direction of the 25-21 edge I get a much more compact layout:
I guess this is because Graphviz strongly believes that all edges should point downwards. Perhaps I tell Graphviz that it is ok for some edges to point upwards?
You can play with the graph here.
Yes, dot definitely strongly believes that all edges should point downwards! While you can indicate that specific edges can skip that rule (reversing edge direction, rank=same, and constraint=false), I can't think of any way to generally relax the rule. (for details, see https://graphviz.org/doc/info/attrs.html).
But if a hierarcical view is not important, try some of the other engines (neato, fdp, circo, twopi). This is an "eye-of-the-beholder" thing, but I liked neato -Nlen=1.8 -Gmode=hier -Goverlap=false
Giving:
You can annotate the offending edge as "21" -> "25" [dir = "back"]; to keep the original arrow while changing the sense of the hierarchy implicit in the dot layout.
using constraint = false can help in some circumstances, but it often results in the layout of the edge to be routed in an unexpected (read ugly) path.
I have a dot graphviz file that geneates the following output:
http://www.qlands.com/other_files/test.png
However the output is organized vertically. If I setup the size to be for example 8.27 inches; How can I distribute the elements around a box of 8.27 x 8.27 inches?
Your graph is a directed graph layed out with dot from left to right, and the first rank contains many nodes which results in a very high image.
The main tool to break up graphs with this problem is unflatten:
unflatten is a preprocessor to dot that is used to improve the aspect
ratio of graphs having many leaves or disconnected nodes. The usual
layout for such a graph is generally very wide or tall. unflatten
inserts invisible edges or adjusts the minlen on edges to improve
layout compaction.
You may combine this with other tools and techniques to get the result you want:
Use the unflatten utility - please see this answer for a detailed example using unflatten.
Use invisible edges to introduce new ranks (basically what unflatten does automatically, but with human inspiration... example also here)
If you need the output to be of this exact size, be sure to understand graphviz's various attributes which have an impact on it, such as size, margin, ratio... (see also this and yet another answer providing details)
Finally, you could simply use a different layout (neato for example)
I have a lot of polygons. Ideally, all the polygons must not overlap one other, but they can be located adjacent to one another.
But practically, I would have to allow for slight polygon overlap ( defined by a certain tolerance) because all these polygons are obtained from user hand drawing input, which is not as machine-precised as I want them to be.
My question is, is there any software library components that:
Allows one to input a range of polygons
Check if the polygons are overlapped more than a prespecified tolerance
If yes, then stop, or else, continue
Create mesh in terms of coordinates and elements for the polygons by grouping common vertex and edges together?
More importantly, link back the mesh edges to the original polygon(s)'s edge?
Or is there anyone tackle this issue before?
This issue is a daily "bread" of GIS applications - this is what is exactly done there. We also learned that at a GIS course. Look into GIS systems how they address this issue. E.g. ArcGIS define so called topology rules and has some functions to check if the edited features are topologically correct. See http://webhelp.esri.com/arcgisdesktop/9.2/index.cfm?TopicName=Topology_rules
This is pretty long, only because the question is so big. I've tried to group my comments based on your bullet points.
Components to draw polygons
My guess is that you'll have limited success without providing more information - a component to draw polygons will be very much coupled to the language and UI paradigm you are using for the rest of your project, ie. code for a web component will look very different to a native component.
Perhaps an alternative is to separate this element of the process out from the rest of what you're trying to do. There are some absolutely fantastic pre-existing editors that you can use to create 2d and 3d polygons.
Inkscape is an example of a vector graphics editor that makes it easy to enter 2d polygons, and has the advantage of producing output SVG, which is reasonably easy to parse.
In three dimensions Blender is an open source editor that can be used to produce arbitrary geometries that can be exported to a number of formats.
If you can use a google-maps API (possibly in an native HTML rendering control), and you are interested in adding spatial points on a map overlay, you may be interested in related click-to-draw polygon question on stackoverflow. From past experience, other map APIs like OpenLayers support similar approaches.
Check whether polygons are overlapped
Thomas T made the point in his answer, that there are families of related predicates that can be used to address this and related queries. If you are literally just looking for overlaps and other set theoretic operations (union, intersection, set difference) in two dimensions you can use the General Polygon Clipper
You may also need to consider the slightly more generic problem when two polygons that don't overlap or share a vertex when they should. You can use a Minkowski sum to dilate (enlarge) two and three dimensional polygons to avoid such problems. The Computational Geometry Algorithms Library has robust implementations of these algorithms.
I think that it's more likely that you are really looking for a piece of software that can perform vertex welding, Christer Ericson's book Real-time Collision Detection includes extensive and very readable description of the basics in this field, and also on related issues of edge snapping, crack detection, T-junctions and more. However, even though code snippets are included for that book, I know of no ready made library that addresses these problems, in particular, no complete implementation is given for anything beyond basic vertex welding.
Obviously all 3D packages (blender, maya, max, rhino) all include built in software and tools to solve this problem.
Group polygons based on vertices
From past experience, this turned out to be one of the most time consuming parts of developing software to solve problems in this area. It requires reasonable understanding of graph theory and algorithms to traverse boundaries. It is worth relying upon a solid geometry or graph library to do the heavy lifting for you. In the past I've had success with igraph.
Link the updated polygons back to the originals.
Again, from past experience, this is just a case of careful bookkeeping, and some very careful design of your mesh classes up-front. I'd like to give more advice, but even after spending a big chunk of the last six months on this, I'm still struggling to find a "nice" way to do this.
Other Comments
If you're interacting with users, I would strongly recommend avoiding this issue where possible by using an editor that "snaps", rounding all user entered points onto a grid. This will hopefully significantly reduce the amount of work that you have to do.
Yes, you can use OGR. It has python bindings. Specifically, the Geometry class has an Intersects method. I don't fully understand what you want in points 4 and 5.
To simplify the problem, I have a graph that contains nodes and edges which are on a 2D plane.
What I want to be able to do is click a button and it make the automatically layout the graph to look clean. By that I mean minimal crossing of edges, nice space between nodes, maybe even represent the graph scale (weighted edges).
I know this is completely subjective of what is a clean looking graph, but does anyone know of an algorithm to start with, rather than reinventing the wheel?
Thanks.
You will find http://graphdrawing.org/ and this tutorial, by Roberto Tamassia, professor at Brown University, quite helpful.
I like a lot Force-Directed Techniques (pp. 66-72 in the tutorial) like the Spring Embedder.
You assume there is a spring or other force between any two adjacent nodes and let nature (simulation) do the work :)
I would suggest that you take a look at at graphviz. The dot program can take a specification of a graph and generate an image of the network for you somewhat "cleanly". I've linked to the "theory" page that gives you some links that might be relevant if you're interested in the theoretical background. The library and tools themselves are mature enough if you simply want a solution to a problem with layout that you're facing.
I would say as Noufal Ibrahim, but you could also look more precisely at the C API of the graphviz project. It includes a lib to build your graph (libgraph.pdf) with all the nodes and edges, and a lib to layout the graph (libgvc.pdf) (just compute each nodes position), so you can then display it in your own UI for example.
Also JGraph if you want the layouts in Java (I work on the project).
A good visual guide how the most popular layouts actually look: follow the link
I am building a dot file to represent computer hardware and the physical connections to a network switch and displays. I have it looking ok when processed by the dot program but I think I really want it processed by neato to create a more "free form" picture as it starts to grom. Right now when I run my large file with neato, everything is overlapping.
I am trying to figure out the syntax on where to define the overlap attribute. Below is a subset of my dot file.
graph g {
node [shape=record,height=.1];
PC8[label="{{<GigE1>GigE1|<GigE2>GigE2}|{<name>PC8}|{<dvi1>dvi1|<dvi2>dvi2|<dvi3>dvi3|<dvi4>dvi4}}"];
PC9[label="{{<GigE1>GigE1|<GigE2>GigE2}|{<name>PC9}|{<dvi1>dvi1|<dvi2>dvi2|<dvi3>dvi3|<dvi4>dvi4}}"];
C1[label = "{{<dvi1>dvi1}|{<name>C1}}"];
C2[label = "{{<dvi1>dvi1}|{<name>C2}}"];
C3[label = "{{<dvi1>dvi1}|{<name>C3}}"];
C4[label = "{{<dvi1>dvi1}|{<name>C4}}"];
D1[label = "{{<dvi1>dvi1}|{<name>D1}}"];
D2[label = "{{<dvi1>dvi1}|{<name>D2}}"];
"PC8":dvi1 -- "C1":dvi1;
"PC8":dvi2 -- "C2":dvi1;
"PC8":dvi3 -- "C3":dvi1;
"PC8":dvi4 -- "C4":dvi1;
"PC9":dvi1 -- "D1":dvi1;
"PC9":dvi2 -- "D2":dvi1;
}
Well, as with most questions...soon after I posted the I figured out the answer. I needed to add graph [overlap=false]; at the top of the file.
Do it like this:
graph g {
overlap = false;
node [shape=record,height=.1];
/* ... */
}
Setting overlap to false will work for neato as the community wiki answer says; however, if the graph exhibits any kind of regularity or symmetry, [overlap=false] will often mess it up by jiggling the nodes around to make them not overlap.
Use [overlap=false] as a last resort.
All node overlaps that are outputted from neato can be viewed as occurring because the nodes are too big relative to the edges. You can make any overlaps go away by making the nodes smaller and preserve symmetry in the graph drawing by setting [overlap=scale]. Quoting the Neato user manual:
To improve clarity, it is sometimes helpful to eliminate overlapping
nodes or edges. One way to eliminate node overlaps is just to scale up
the layout (in terms of the center points of the nodes) as much as
needed. This is enabled by setting the graph attribute overlap=scale.
This transformation preserves the overall geometric relationships in
the layout, but in bad cases can require high scale factors
As the documentation says [overlap=scale] can result in graph drawings that are unacceptably large, but if it does not its output is generally going to be better looking than [overlap=false].