Introduction

ged2dot is a GEDCOM to Graphviz converter.

The latest version is v24.2, released on 2024-02-01.

Description

ged2dot is a script that takes a GEDCOM file and tries to visualize it using Graphviz's dot tool. The basic idea is that you can map individuals and families to graph nodes and connections between them to graph edges, then dot takes care of the rest. What's unique about ged2dot is that it allows more than showing ancestors and descendants of a single individual (what you can easily do with other existing family editor software).

It looks like this:

screenshot

Contributing

ged2dot is free and open source. You can find the source code on GitHub and issues and feature requests can be posted on the issue tracker. If you'd like to contribute, please consider opening a pull request.

License

Use of this source code is governed by a MPL-style license that can be found in the LICENSE file.

Installation

Download

From GitHub.

Running the script in-place

You can build the code using:

./ged2dot.py --help

You can run the tests using:

make check

Qt-based GUI

The qged2dot.py script is a Qt-based GUI for ged2dot, which can turn the dot output into PNG files.

For macOS, the DMG is not signed digitally, so you need to allow its usage explicitly.

The installer bundles Graphviz for macOS and Windows.

The app icon is by Appzgear.

LibreOffice Draw GEDCOM import filter

The libreoffice/ subdirectory contains a LibreOffice extension, that implements a GEDCOM import filter for Draw. Needless to say, it uses ged2dot internally -- think of it as a GUI for ged2dot, with the additional benefit that you can hand-edit the resulting layout in Draw, if you want.

Its dependencies:

  • It uses Graphviz to process the dot format. In case you don't have Graphviz installed:

    • For Windows, get it here (2.38 is tested).

    • For Linux, use your package manager to install the graphviz package (2.28 is tested).

    • For macOS, install it from brew (2.36 is tested).

  • LibreOffice >= 7.2

Features:

  • Filter detection: you can use File -> Open and select a GEDCOM file, and it'll be opened in Draw automatically.
  • Import options: On import, a graphical dialog can be used to set a subset of the options available in a ged2dotrc.
  • Internally reuses the excellent SVG import filter of LibreOffice, contributed by Fridrich Strba and Thorsten Behrens, so the result can be manually fine-tuned if necessary.
  • Runs on Windows and Linux and macOS.

You can grap a release binary at the releases page -- more on how to to install a LibreOffice extension here.

NOTE: Linux distributions install Python support separately, be sure to install the libreoffice-script-provider-python (deb) or libreoffice-pyuno (rpm) packages before the OXT file.

Once that's done, you'll see something like this if you open a GEDCOM file:

screenshot

Usage

You usually want to customize your input filename, output filenames, the root family and the depth of the graph visitor. You can provide these either by using command-line arguments (see ged2dot.py --help) or by using a configuration file (see ged2dotrc.sample). When using both, the command-line arguments overwrite configuration values.

A typical flow looks like this with a provided test input:

./ged2dot.py --input tests/happy.ged --output test.dot --rootfamily F1 --familydepth 3
dot -Tsvg -o test.svg test.dot

At this point you can open test.svg in your web browser and check the result. Mouse tooltips on the marriage nodes give you family IDs. You can change the familydepth parameter to include less or more nodes around the root family.

Layout

The layout does a Breadth First Search (BFS) traversal on the graph, from the starting family.

This has several benefits over explicitly trying to guess which family belongs to which generation. Some example more tricky cases, which are handled by ged2dot:

  • root family → husband → sister → showing her kids

  • root family → wife → cousin → showing her kid

  • root family → husband → grand father → showing both wives with the matching kids

  • marrying cousins

(ged2dot <= 7.0 allowed multiple layouts, none of them supported the above more tricky cases.)

GEDCOM files don't contain images, but you can put images next to the GEDCOM file, and in that case ged2dot will try to pick them up when generating dot output. The expected location is images/Given Family 1234.jpg, relative to the GEDCOM file. For example, there is a person called Ray Smith in the above screenshot. The birth year string is Y, so the image location has to be images/Ray Smith Y.jpg.

Bugs

For ged2dot, in case a given input results in a runtime crash, it's considered a bug. If you have a fix for it, pull requests on GitHub are welcome. Make sure to run make check before submitting your changes.

For the LibreOffice extension, in case you get an error during opening:

  • For Windows, the log file location is something like:
C:/Users/John/Application Data/LibreOffice/4/user/Scripts/python/log.txt
  • For Linux, start LibreOffice from a terminal, the log is printed to the standard error.

  • For Mac, start LibreOffice from Terminal:

cd /Applications/LibreOffice.app/Contents/program
./soffice --nologo /path/to/test.ged

then the log is printed to the standard error as well.

Icons

Icons are from WPZOOM, in case placeholders have to be used for missing images.

Resources

Development notes

How to set up a virtual env

Create it:

python3.11 -m venv ged2dot-env

Activate it:

. ged2dot-env/bin/activate

Install requirements:

pip install -r requirements.txt

Development cycle

A typical flow is:

... hack hack hack ...
make check-mypy
ged2dot --input test.ged --output test.dot && dot -Tsvg -o test.svg test.dot # test the changes

Once you're happy with your change:

make check # run all tests
... write new tests if coverage regressed ...

Python debugging

To run a single test:

env PYTHONPATH=.:tests python3 -m unittest tests.test_ged2dot.TestMain.test_happy

Maintenance

Ideally CI checks everything before a commit hits master, but here are a few things which are not part of CI:

  • Run tools/requirements.py once a month and make sure Python dependencies are reasonably up to date.

Version descriptions

master

  • qget2dot is now ported to qt 6
  • the macOS port is now deprecated, CI & release binary will be removed in the next release

24.2

  • Use ordering=out on family nodes to try to control the order of children nodes
  • Fix crash on non-existing root family

7.6

  • Fix crash on non-int line start
  • Fix crash on invalid utf-8 lines

7.5

  • new config option: direction (defaults to both, can be child)

7.4

  • Fail nicer when the specified root family doesn't exist
  • Document expected image location

7.3

  • Resolves: gh#179 show date of marriage for a family

7.2

  • Better support for GenoPro-generated GED files (Andreas Hrubak)
  • Keep aspect ratio of images in the PDF output with long names (humaita)
  • New --relpath option to use relative paths when referring to images
  • Specify the font used for text explicitly to improve centering
  • Better handling of death-only dates
  • Add --birthformat option
  • Switch to svg placeholders
  • Add icon for marriage

7.1

  • Rewritten ged2dot to use BFS for graph traversal (much more robust, though some incompatible old options are now ignored)
  • Resolves: gh#19 fix infinite recursive stack in Individual.str and Family.str
  • Resolves: gh#13 marrying cousins is now handled
  • Comes with a qged2dot GUI (packaged as DMG for macOS, MSI for Windows)

7.0

  • tested with LibreOffice 7.0
  • pylint fixes
  • Use sys.stderr.write instead of print to print errors (Colin Chargy)
  • add better error handling and error out on lack of rc file (Doug Hughes)

6.0

  • fixed to work with 64-bit LibreOffice

0.8

  • fixed to work with LibreOffice 6.1

0.7

  • minor fixes, tested with LibreOffice 5.4

0.6

  • two layout fixes, tested with LibreOffice 5.1

0.5

  • pylint fixes, tested with LibreOffice 4.4

0.4

  • New 'layout = Descendants' configuration key to show descendants, not ancestors of the root family.

  • Next to "M" and "F", "U" is now accepted as a sex.

  • Ancestors layout now handles if the root family has children.

  • Mac instructions.

0.3

  • Handle UTF-8 BOM at the beginning of .ged files
  • Fixed layout crash on missing previous parent

0.2

  • Initial LibreOffice extension

0.1

  • Initial release

Contributors