An Introduction to GraphViz

How to use command-line tools and basic GraphViz utilities to produce graphs both simple and complex.
Drawing a Monthly Calendar

Here we are going to walk through the simple task of creating a monthly calendar by using a small Perl script. See the relevant Perl code below for more information about the command-line arguments of the script.

You can experiment with sizes, colors and shapes of the output to customize the calendar and make it look the way you want. This small example simply shows what a scripting language combined with a smart tool can do. See Figure 4 for the output and Listing 4 for the Perl source code.

Figure 4. A Month Calendar

Listing 4. Perl Source Code for Figure 4

#!/usr/bin/perl -w

# $Id:,v 3.1 2004/02/05 22:03:32 mtsouk Exp mtsouk $
# A perl script to generate monthly
# calendars using dot.
# Mihalis Tsoukalos 2004
#  * * * * * * * * * * * * * * * * * * * * * * * *

# Command line arguments
# MonthName MonthYear NofDays StartingDay
# MonthName: This is given by the user.
# Year: This is given by the user.
# NofDays: The number of the month's days.
# Month Starting Day: 0 for Sunday etc.

die <<Thanatos unless @ARGV;
    $0 MonthName MonthYear NofDays StartingDay
    MonthName: The name of the month in the output.
    Year: The Year to appear in the output.
    NofDays: The number of the month's days.
    Month first Day: 0 for Sunday, 1 for Monday etc.

if ( @ARGV != 4 )
    die <<Thanatos
    usage info:
        Please use exactly 4 arguments!

# Get the values of the command line arguments
($MonthName, $Year, $NofDays, $SDay) = @ARGV;

# This will tell how many weeks exist in the month
$NofWeeks = (($NofDays + $SDay) / 7);
if ( $NofWeeks > int($NofWeeks) )
    $NofWeeks = int($NofWeeks) + 1;

my $filename = $MonthName.".dot";
open(OUTPUT, "> $filename " ) ||
    die "Cannot create $filename: $!\n";

$temp = $SDay;

# Fix the first week
while ( $temp > 0 )
    $month[$temp] = "em".$temp;

for ( $i = 0; $i<$NofDays; $i++ )
    $month[$i+$SDay+1] = "day".($i+1)." ";

print OUTPUT <<PRE;
digraph G

    subgraph weekdays
        node [ style=filled, color=lightgray, \\
            height=.60, width=1.15];
        label = "WeekDays";

    "$MonthName $Year" [shape=Msquare];
    "$MonthName $Year" -> sun;
    "$MonthName $Year" -> $month[1];
    "$MonthName $Year" -> $month[8];
    "$MonthName $Year" -> $month[15];
    "$MonthName $Year" -> $month[22];

# All months have at least 4 weeks (not full).
# Checking is being done here to see
# if the current months has more that 4 weeks.
if (defined $month[29] )
print OUTPUT <<WEEK5;
    "$MonthName $Year" -> $month[29];

# The maximum number of weeks a month can have is 6
if( defined $month[36] )
print OUTPUT <<WEEK6;
    "$MonthName $Year" -> $month[36];

for ( $i=0; $i<$NofWeeks; $i++ )
    print OUTPUT "subgraph week".($i+1);
    print OUTPUT "{";
    print OUTPUT "node [ height=.60, width=.85];";

    for ( $j=1; $j<7; $j++)
        if (defined $month[$i*7+$j])
            print OUTPUT $month[$i*7+$j];
            if (defined $month[$i*7+$j+1])
                print OUTPUT " -> ";

    # The 7th day of each week is a special case
    # as it does not have a -> after.
    if (defined $month[$i*7+7] )
        print OUTPUT $month[$i*7+7].";\n";
    print OUTPUT "}\n";

# Type the empty days into the output file
$temp = $SDay;
while ( $temp > 0 )
    print OUTPUT "em".$temp;
    print OUTPUT " [ shape=box, label=\"\" ];";
    print OUTPUT "\n";

# Type the days into the output file
for ( $i=1; $i <= $NofDays; $i++ )
    print OUTPUT "\t";
    print OUTPUT "day".$i;
    print OUTPUT " [shape=box, label=\"".$i."\"];";
    print OUTPUT "\n";


    sun [shape=egg, label="Sunday"];
    mon [shape=egg, label="Monday"];
    tue [shape=egg, label="Tuesday"];
    wed [shape=egg, label="Wednesday"];
    thu [shape=egg, label="Thursday"];
    fri [shape=egg, label="Friday"];
    sat [shape=egg, label="Saturday"];

close(OUTPUT) ||
    die "Cannot close $filename: $!\n";

exit 0;

More Complex Graph Drawings

Now we are going to look at some more complex examples of what you can do with GraphViz. We start with building an entity relation diagram (used in DBMS systems) using NEATO. An entity relation diagram is a graph that represents entity sets, attributes and relationships. It is common practice to represent entity sets as rectangles, attributes as ovals and relationships as diamonds. GraphViz easily can be used to construct such diagrams, as the example below shows.

The key point to remember here is to change the shapes--rectangles, ovals and diamonds--among the different kinds of elements. This can be done with the shape attribute. See Figure 5 for the output and Listing 5 for the NEATO source code.

Figure 5. An Entity Relation Diagram

Listing 5. Source Code for Figure 5

graph G



    university[label="University Department"];


    university -- StUnDe [label="1", len=3];
    StUnDe -- student [label="n", len=2];

    student -- id;
    student -- name;
    student -- email;

    university -- uname;
    university -- address;

Next up is the example of an undirected graph with costs on edges using NEATO. This is a useful example, because this kind of graph can be used to represent network structures, while the cost values help define the best routing tables for either local or wide area networks. It should be helpful for easily understanding network topologies. This figure has been taken from page 174 of The Design and Analysis of Computer Algorithms (see Resources). See Figure 6 for the output and Listing 6 for the NEATO source code.

Figure 6. An Undirected Graph with Costs

Listing 6. Source Code for Figure 6

graph G
        edge [len=2];

        V1 -- V2 [label="20"];
        V2 -- V3 [label="15"];
        V3 -- V4 [label="3"];
        V4 -- V5 [label="17"];
        V5 -- V6 [label="28"];
        V6 -- V1 [label="23"];

        V7 -- V1 [label="1"];
        V7 -- V2 [label="4"];
        V7 -- V3 [label="9"];
        V7 -- V4 [label="16"];
        V7 -- V5 [label="25"];
        V7 -- V6 [label="36"];

If you put the six V7 connections first, the output is not that great; at least, it is not similar to the original figure. Of course, the amount of information is the same. You can make some changes to the file and see how the output looks.



Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

Re: An Introduction to GraphViz

Anonymous's picture

Readers might be wondering why dia doesn't include dot, or KDE, or...

And the answer's the license, which is kind of open source, but not quite. OSI don't seem to regard it as so, anyway, and it's in nonfree in Debian.

However, for those many cases where the license doesn't matter so long as you can get the tool, graphviz is a great set of tools to have around.

Re: An Introduction to GraphViz

Anonymous's picture

Any reason you didn't mention Leon Brocard's excellent GraphViz Perl module, which makes this so much easier?

To say nothing of the other GraphViz related modules on CPAN.

Re: An Introduction to GraphViz

Anonymous's picture

Great article!
I wrote a web log analyzer that outputs a graphviz
graph from the web server logs (
and I think I can modify the program to produce a better
output thanks to this article.

Btw a note about the graphviz's license: it's not opensource
if I remember correctly (or at least not an OSI approved

Graphviz (AT&T source code) license

Stephen North's picture

Thank you for the nice articles about Graphviz.

We're aware of the problems about the AT&T Source
Code License, and expect to have some good news shortly.


Graphviz is now under the CPL

Stephen North's picture

We hope this will be beneficial to the open source community.
Please visit for downloads and other info.