Introduction
ged2dot is a GEDCOM to Graphviz converter.
The latest version is v24.8, released on 2024-08-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:
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.
The installer bundles Graphviz for 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).
-
-
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.
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:
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
- Put spouses into a subgraph cluster, so they are closer to each other (Gregory Dudek)
24.8
- qget2dot is now ported to qt 6
- the macOS port is now deprecated, CI & release binary will be removed in the next release
- Support a few more image types or file suffixes, notably jpg as well as png (Gregory Dudek)
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 bechild
)
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