The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Tree::Cladogram - Render a cladogram using Imager or Image::Magick

Synopsis

This is scripts/imager.pl:

        #!/usr/bin/env perl

        use strict;
        use warnings;

        use Getopt::Long;

        use Pod::Usage;

        use Tree::Cladogram::Imager; # Or Tree::Cladogram::ImageMagick.

        # ----------------------------------------------

        my($option_parser) = Getopt::Long::Parser -> new;

        my(%option);

        if ($option_parser -> getoptions
        (
                \%option,
                'draw_frame=i',
                'frame_color=s',
                'help',
                'input_file=s',
                'leaf_font_file=s',
                'leaf_font_size=i',
                'output_file=s',
                'print_tree=i',
                'title=s',
                'title_font_file=s',
                'title_font_size=s',
        ) )
        {
                pod2usage(1) if ($option{'help'});

                exit Tree::Cladogram::Imager -> new(%option) -> run;
        }
        else
        {
                pod2usage(2);
        }

See also scripts/image.magick.pl.

As you can see, you create an object and then call "run()".

And this is the heart of scripts/imager.sh:

        perl -Ilib scripts/plot.pl \
            -debug 0 \
            -draw_frame $FRAME \
            -input_file data/$i.01.clad \
            -leaf_font_file $LEAF_FONT_FILE \
            -output_file data/$i.01.png \
            -title "$TITLE" \
            -title_font_file $TITLE_FONT_FILE

See also scripts/image.magick.sh.

Description

Tree::Cladogram provides a mechanism to turn a tree into a cladogram image. The image is generated using Imager or Image::Magic.

The image type created is determined by the suffix of the output file. See "What image formats are supported?" for details.

The details of the cladogram are read from a text file. See the "FAQ" for details.

For information about cladograms, see https://en.wikipedia.org/wiki/Cladogram.

For another sample of a cladogram, see http://phenomena.nationalgeographic.com/2015/12/11/paleo-profile-the-smoke-hill-bird/.

Sample input is shipped as data/*.clad. The corresponding output is shipped as data/*.png, and is on-line:

wikipedia.01.clad output by Imager

wikipedia.01.clad output by Image::Magick

nationalgeographic.01.clad output by Imager

nationalgeographic.01.clad output by Image::Magick

Distributions

This module is available as a Unix-style distro (*.tgz).

See http://savage.net.au/Perl-modules/html/installing-a-module.html for help on unpacking and installing distros.

Installation

Install Tree::Cladogram as you would for any Perl module:

Run:

        cpanm Tree::Cladogram

or run:

        sudo cpan Tree::Cladogram

or unpack the distro, and then:

        perl Makefile.PL
        make (or dmake or nmake)
        make test
        make install

Constructor and Initialization

new() is called as my($cladotron) = Tree::Cladogram::Imager -> new(k1 => v1, k2 => v2, ...) or as my($cladotron) = Tree::Cladogram::ImageMagick -> new(k1 => v1, k2 => v2, ...).

It returns a new object of type Tree::Cladogram::Imager or Tree::Cladogram::ImageMagick.

Key-value pairs accepted in the parameter list (see corresponding methods for details [e.g. "branch_color([$string])"]):

o branch_color => $string

Specify the color of the branches in the tree.

See (in the FAQ) "What colors are supported?" for details about colors.

Default: '#7e7e7e' (gray).

o branch_width => $integer

Specify the thickness of the branches.

Default: 3 (px).

o debug => $Boolean

Specify non-production effects.

Currently, the only extra effect is to draw fuchsia boxes around the leaf names.

Frankly, this helped me debug the Image::Magick side of things.

Default: 0 (no extra effects).

o draw_frame => $Boolean

Specify that you want a frame around the image.

Default: 0 (no frame).

o final_x_step => $integer

Specify an extra bit for the length of the final branch leading to the names of the leaves.

Default: 30 (px).

o frame_color => $string

Specify the color of the frame, if any.

See also draw_frame.

Default: '#0000ff' (blue).

o input_file => $string

Specify the name of the *.clad file to read. Of course, the suffix does not have to be 'clad'.

The format of this file is specified in the "FAQ".

Default: ''.

o leaf_font_color => $string

Specify the font color of the name of each leaf.

Default: '#0000ff' (blue).

o leaf_font_file => $string

Specify the name of the font file to use for the names of the leaves.

You can use path names, as per the default, or - using Image::Magick -, you can just use the name of the font, such as 'DejaVu-Sans-ExtraLight'.

Default: '/usr/share/fonts/truetype/freefont/FreeMono.ttf'.

o leaf_font_size => $integer

Specify the size of the text used for the name of each leaf.

Default: 16 (points).

o left_margin => $integer

Specify the distance from the left of the image to the left-most point at which something is drawn.

This also sets the right-hand margin.

Default: 15 (px).

o output_file => $string

Specify the name of the image file to write.

Image formats supported are anything supported by Imager or Image::Magick. See the "What image formats are supported?" for details.

Default: '' (no output).

o print_tree => $Boolean

Specify that you want to print the tree constructed by the code.

This option is really a debugging aid.

Default: 0 (no tree).

o title => $string

Specify the title to draw at the bottom of the image.

Default: '' (no title).

o title_font_color => $string

Specify the font color of the title.

Default: '#000000' (black).

o title_font_file => $string

Specify the name of the font file to use for the title.

You can use path names, as per the default, or - using Image::Magick -, you can just use the name of the font, such as 'DejaVu-Sans-ExtraLight'.

Default: '/usr/share/fonts/truetype/freefont/FreeSansBold.ttf'.

o title_font_size => $integer

Specify the size of the text used for the name of the title.

Default: 16 (points).

o top_margin => $integer

Specify the distance from the top of the image to the top-most point at which something is drawn.

This also sets the bottom margin.

Default: 15 (px).

o x_step => $integer

The horizontal length of branches.

See also "final_x_step([$integer])" and "y_step([$integer])".

Default: 50 (px).

o y_step => $integer

The vertical length of the branches.

Note: Some vertical branches will be shortened if the code detects overlapping when leaf names are drawn.

See also "x_step([$integer])".

Default: 40 (px).

Methods

branch_color([$string])

Get or set the color used to draw branches.

See (in the FAQ) "What colors are supported?" for details about colors.

branch_color is a parameter to "new()".

branch_width([$integer])

Get or set the width of branches.

branch_width is a parameter to "new()".

debug([$Boolean])

Get or set the option to activate debug mode.

debug is a parameter to "new()".

draw_frame([$Boolean])

Get or set the option to draw a frame on the image.

draw_frame is a parameter to "new()".

final_x_step([$integer])

Get or set a bit extra for the horizontal length of the branch leading to leaf names.

final_x_step is a parameter to "new()".

frame_color([$string])

Get or set the color of the frame.

frame_color is a parameter to "new()".

input_file([$string])

Get or set the name of the input file.

input_file is a parameter to "new()".

leaf_font_color([$string])

Get or set the font color of the text used to draw leaf names.

leaf_font_color is a parameter to "new()".

leaf_font_file([$string])

Get or set the name of the font file used for leaf names.

You can use path names, as per the default, or - using Image::Magick -, you can just use the name of the font, such as 'DejaVu-Sans-ExtraLight'.

leaf_font_file is a parameter to "new()".

leaf_font_size([$integer])

Get or set the size of the font used to draw leaf names.

leaf_font_size is a parameter to "new()".

left_margin([$integer])

Get or set the distance from the left edge at which drawing starts.

This also sets the right margin.

left_margin is a parameter to "new()".

maximum_x()

Get the right-most point at which something was drawn.

This value is determined by examining the bounding boxes of all leaf names.

In the case that the title is wider that the right-most leaf's name, maximum_x reflects this fact.

maximum_y()

Get the bottom-most point at which something was drawn.

This value includes the title, if any.

new()

See "Constructor and Initialization" for details on the parameters accepted by "new()".

output_file([$string])

Get or set the name of the output file.

The file suffix determines what type of file is written.

For more on supported image types, see the "What image formats are supported?".

output_file is a parameter to "new()".

Get or set the option to print the tree constructed by the code. This is basically a debugging option.

print_tree is a parameter to "new()".

root()

Get the root of the tree built by calling run(). This tree is an object of type Tree::DAG_Node.

For printing the tree, see "print_tree([$Boolean])".

Normally, end-users would never call this method.

run()

After calling "new()", this is the only other method you would normally call.

title([$string])

Get or set the title to be drawn at the bottom of the image.

Note: It's vital you set the title before calling "run()", since the width of the title might be greater that the width of the tree, and the width of the title would then be used to determine the width of the image to create.

title is a parameter to "new()".

title_font_color([$string])

Get or set the font color of the text used to draw the title.

title_font_color is a parameter to "new()".

title_font_file([$string])

Get or set the name of the font file used for the title.

You can use path names, as per the default, or - using Image::Magick -, you can just use the name of the font, such as 'DejaVu-Sans-ExtraLight'.

title_font_file is a parameter to "new()".

title_font_size([$integer])

Get or set the size of the font used to draw the title.

title_font_size is a parameter to "new()".

top_margin([$integer])

Get or set the distance from the top edge at which drawing starts.

This also sets the bottom margin.

top_margin is a parameter to "new()".

x_step([$integer])

Get or set the length of horizontal branches.

See also final_x_step.

x_step is a parameter to "new()".

y_step([$integer])

Get or set the length of vertical branches.

Note: Some vertical branches will be shortened if the code detects overlapping when leaf names are drawn.

y_step is a parameter to "new()".

Scripts and data files shipped with this module

Scripts

See scripts/*.pl and scripts/*.sh.

o Debian.font.list.pl

Outputs to my web server's doc root, which is in Debian's RAM disk, a file called "$ENV{DR}/misc/Debian.font.list.png".

The output file is not part of the distro (being 3.3 Mb), but is on line at http://savage.net.au/misc/Debian.font.list.png.

o image.magick.pl

The program you would normally use to drive Tree::Cladogram::ImageMagick.

See also image.magick.sh.

o image.magick.sh

A convenient way to run image.magick.pl.

o imager.pl

The program you would normally use to drive Tree::Cladogram::Imager.

See also imager.sh.

o imager.sh

A convenient way to run imager.pl.

o pod2html.sh

A simple way for me to convert the docs into HTML.

o test.image.magick.pl

Outputs data/test.image.magick.png. I used this program to experiment with Image::Magick while converting Tree::Cladogram::Imager into Tree::Cladogram::ImageMagick.

o test.image.magick.sh

A convenient way to run test.image.magick.pl.

Data files

See data/*.

o nationalgeographic.01.clad

This sample input file is discussed just below, at the start of the "FAQ".

o nationalgeographic.01.png

This is the output of rendering nationalgeographic.01.clad with Imager.

o nationalgeographic.02.png

This is the output of rendering nationalgeographic.01.clad with Image::Magick.

o test.image.magick.png

The is is output of scripts/test.image.magick.pl.

o wikipedia.01.clad

This sample input file is discussed just below, at the start of the "FAQ".

o wikipedia.01.png

This is the output of rendering wikipedia.01.clad with Imager.

o wikipedia.02.png

This is the output of rendering wikipedia.01.clad with Image::Magick.

FAQ

What is the format of the input file?

Sample 1 - https://en.wikipedia.org/wiki/Cladogram:

                +---- Beetles
                |
                |
        Root ---+       +---- Wasps, bees, ants
                |       |
                |       |
                1---+   +---- Butterflies, moths
                    |   |
                    |   |
                    2---+
                        |
                        |
                        +---- Flies

This is the data file (shipped as data/cladogram.01.clad). The format is defined formally below:

        Parent  Place  Node
        root    above  Beetles
        root    below  1
        1       above  Wasps, bees, ants
        1       below  2
        2       above  Butterflies, moths
        2       below  Flies

Output: Using Imager and using Image::Magick.

Sample 2 - http://phenomena.nationalgeographic.com/2015/12/11/paleo-profile-the-smoke-hill-bird/:

                +--- Archaeopterix lithographica
                |
                |
                |
        Root ---+   +--- Apsaravis ukhaana
                |   |
                |   |
                |   |
                1---+   +--- Gansus yumemensis
                    |   |
                    |   |
                    |   |
                    2---+   +--- Ichthyornis dispar
                        |   |
                        |   |       +--- Gallus gallus
                        |   |       |
                        3---+   5---+
                            |   |   |
                            |   |   +--- Anas clypeata
                            |   |
                            4---+
                                |   +--- Pasquiaornis
                                |   |
                                |   |
                                6---+   +--- Enaliornis
                                    |   |
                                    |   |
                                    |   |
                                    7---+   +--- Baptornis advenus
                                        |   |
                                        |   |       +--- Brodavis varnei
                                        |   |       |
                                        8---+   10--+
                                            |   |   |
                                            |   |   +--- Brodavis baileyi
                                            |   |
                                            9---+
                                                |   +--- Fumicollis hoffmani
                                                |   |
                                                |   |
                                                11--+   +--- Parahesperornis alexi
                                                    |   |
                                                    |   |
                                                    12--+
                                                        |
                                                        |
                                                        +--- Hesperornis regalis

This is the data file (shipped as data/nationalgeographic.01.clad). The format is defined formally below:

        Parent  Place  Node
        root    above  Archaeopterix lithographica
        root    below  1
        1       above  Apsaravis ukhaana
        1       below  2
        2       above  Gansus yumemensis
        2       below  3
        3       above  Ichthyornis dispar
        3       below  4
        4       above  5
        4       below  6
        5       above  Gallus gallus
        5       below  Anas clypeata
        6       above  Pasquiaornis
        6       below  7
        7       above  Enaliornis
        7       below  8
        8       above  Baptornis advenus
        8       below  9
        9       above  10
        9       below  11
        10      above  Brodavis varnei
        10      below  Brodavis baileyi
        11      above  Fumicollis hoffmani
        11      below  12
        12      above  Parahesperornis alexi
        12      below  Hesperornis regalis

Output: Using Imager and using Image::Magick.

File format:

o Words and numbers on each line are tab separated

Oh, all right. You can use any number of spaces too, but why bother?

o There are 3 columns
o The first line must match /Parent\tPlace\tNode/i

For non-programmers, the /.../ is a regular expression, just saying the program tests for that exact string. The '\t's represent tabs and the suffix 'i' means use a case-insensitive test.

o Thereafter, column 1 is the name of the node
o The word 'root' is (also) case-insensitive
o Every node has 2 mandatory lines

One for the daughter 'above' the current node, and one for the daughter 'below'.

o Column 2 specifies where the daughter appears in relation to the node
o All words after the 2nd column are the name of that daughter
o Fabricate skeleton nodes to hold together the nodes you are interested in
o Use digits for the skeleton nodes' names

The code hides the name of nodes which match /^(\d+|root)$/.

Which versions of the renderers did you use?

Imager V 1.004.

Image::Magick V 6.9.3-0 Q16.

For help installing Image::Magick under Debian, see http://savage.net.au/ImageMagick/html/Installation.html.

What image formats are supported?

My default install of Imager lists:

        bmp
        ft2
        ifs
        png
        pnm
        raw

Image::Magick supports a huge range of formats (221 actually). To list them, run scripts/test.image.magick.pl. Note: This program writes to data/test.image.magick.png.

What colors are supported?

See Imager::Color for Imager's docs on color. But you're probably better off using Image::Magick's table mentioned next, since my module only accepts colors. It does not allow you to provide an Imager::Color object as a parameter.

See Image::Magick colors for a huge table of both names and hex values.

What fonts are supported?

Check these directories:

o /usr/local/share/fonts
o /usr/share/fonts

If you're using Debian, run fc-list for a list of installed fonts.

More information on Debian's support for fonts can be found on Debian's wiki.

See http://savage.net.au/misc/Debian.font.list.png for the fonts on my laptop. Note: This file is 3.3 Mb, so you may have to zoom it to 500% to make it readable.

See scripts/imager.sh and scripts/image.magick.sh for lists of fonts I have played with while developing this module.

Further, note this text copied from the docs for Imager::Font:

        This module handles creating Font objects used by Imager. The module also handles querying
        fonts for sizes and such. If both T1lib and FreeType were available at the time of compilation
        then Imager should be able to work with both TrueType fonts and t1 Postscript fonts. To check
        if Imager is t1 or TrueType capable you can use something like this:

        use Imager;

        print "Has truetype\n"      if $Imager::formats{tt};
        print "Has t1 postscript\n" if $Imager::formats{t1};
        print "Has Win32 fonts\n"   if $Imager::formats{w32};
        print "Has Freetype2\n"     if $Imager::formats{ft2};

My default install of Imager reports:

        Has Freetype2

How does leaf_font_size interact with y_step?

This might depend on the font, but here are some tests I ran with the one leaf font:

o leaf_font_size 12 works with y_step values of 28 .. 40
o leaf_font_size 16 works with y_step values of 36 .. 44
o leaf_font_size 20 works with y_step values of 40 .. 48
o leaf_font_size 24 works with a y_step value of 48
o leaf_font_size 28 works with a y_step value of 54
o leaf_font_size 32 works with a y_step value of 54
o leaf_font_size 36 works with a y_step value of 72
o leaf_font_size 40 works with a y_step value of 72

Why did you use Tree::DAG_Node and not something like Tree::Simple?

I started with Tree::Simple precisely because it's simple, but found it awkward to use.

I did use Tree::Simple in HTML::Parser::Simple. That module was deliberately kept simple, but before that, and since, I've always gone back to Tree::DAG_Node.

How is overlap between leaves detected?

The process starts by calling the undocumented method _check_for_overlap().

See Also

Bio::Tree::Draw::Cladogram

Imager

Image::Magick

Help installing Image::Magick

Tree::DAG_Node

Machine-Readable Change Log

The file Changes was converted into Changelog.ini by Module::Metadata::Changes.

Version Numbers

Version numbers < 1.00 represent development versions. From 1.00 up, they are production versions.

Repository

https://github.com/ronsavage/Tree-Cladogram

Support

Email the author, or log a bug on RT:

https://rt.cpan.org/Public/Dist/Display.html?Name=Tree::Cladogram.

Author

Tree::Cladogram was written by Ron Savage <ron@savage.net.au> in 2015.

My homepage: http://savage.net.au/

Copyright

Australian copyright (c) 2015, Ron Savage.

        All Programs of mine are 'OSI Certified Open Source Software';
        you can redistribute them and/or modify them under the terms of
        The Perl License, a copy of which is available at:
        http://dev.perl.org/licenses/