Generic Graphml Printer for OcamlGraph

Graphml is a nice and widely used graph description format. This is a micro module to print OcamlGraph - graphs in this format.

The signature is minimal. Since in GraphMl all attributes are typed, we only need two functions to describe the name, type a default value for the attributes of each vertex and edge, and two functions to map the value of each vertex and edge to a key / value list.

module type GraphmlSig =
  sig
    include Graph.Sig.G
    (** the format is (key, type of the key, default value *)
    val default_vertex_properties : (string * string * string option) list
    val default_edge_properties : (string * string * string option) list

    (** the format is (key, value *)
    val data_map_vertex : vertex -> (string * string) list
    val data_map_edge : edge -> (string * string) list
  end
;;

module type GraphmlPrinterSig =
  sig
    type t
    val pp_graph : Format.formatter -> t -> unit
    val to_file : t -> string -> unit
  end

To give a small example, we build a simple graph with three vertex and two edges . In this case we only print the id of the node.

open Graphml

module V = struct
  type t = int
  let compare = compare
  let hash i = i
  let equal = (=)
end

module G = Graph.Imperative.Digraph.ConcreteBidirectional(V)

module Gr = struct
  include G
  let default_vertex_properties = ["id","string",None]
  let default_edge_properties = []
  let data_map_edge e = []
  let data_map_vertex v = ["id",string_of_int v]
end

module GraphPrinter = GraphmlPrinter (Gr) ;;

let print g = GraphPrinter.pp_graph Format.std_formatter g ;;

let g = G.create () in
G.add_vertex g 1 ;
G.add_vertex g 2 ;
G.add_vertex g 3 ;
G.add_edge g 1 2 ;
G.add_edge g 1 3 ;
print g;;

Use use ocamlbuild to compile the lot.

$ocamlbuild -use-ocamlfind -package ocamlgraph test.native

The result looks like this. I agree the formatting is not perfect …

<?xml version="1.0" encoding="UTF-8"?>
<graphml xmlns="http://graphml.graphdrawing.org/xmlns"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns
     http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd">
<key id="id" for="node" attr.name="id" attr.type="string">

<graph id="G" edgedefault="directed">
<node id="n1">
 <data key="id">1</data> </node>
 <node id="n2">
 <data key="id">2</data>
 </node>
 <node id="n3">
 <data key="id">3</data>
 </node>

<edge id="e131199" source="n1" target="n2">
 </edge>
 <edge id="e196798" source="n1" target="n3">
 </edge>

</graph></graphml>

Using GraphTool, you can easily access a zillion more algorithms from the boost graph library. To be sincere, GraphTool accepts also graphs in dot and gml format. Graphml is the default format for GraphTool as it contains precise type information.

#! /usr/bin/env python
from graph_tool.all import *

g = load_graph("ex.xml")
graph_draw(g, pos=None, output_size=(420, 420), output="ex.pdf")

Update

A refined version of the module Graphml is going to be included in the next release of ocamlgraph ! The tgz is attached to this message.

Example