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

NAME

Color::TupleEncode - Encode a tuple (vector) into a color - useful for generating color representation of a comparison of multiple values.

VERSION

Version 0.11

SYNOPSIS

Given a tuple (e.g. three numbers) , apply color-coding method to encode the tuple by a color in HSV (hue, saturation, value) space. For a visual tour of the results, see http://mkweb.bcgsc.ca/tupleencode/.

  use Color::TupleEncode;

  # By default the encoding method Color::TupleEncode::Baran will be used

  # initialize and define in one step
  $encoder = Color::TupleEncode->new(tuple=>[$a,$b,$c]);

  # pass in some options understood by the encoding implementation
  %options = {-ha=>30, -saturation=>{dmin=>0.2,dmax=>0.8}};
  $encoder = Color::TupleEncode->new(tuple=>[$a,$b,$c],options=>\%options);

  # initialize tuple directly
  $encoder->set_tuple($a,$b,$c);
  $encoder->set_tuple([$a,$b,$c]);

  # obtain RGB (0 <= R,G,B <= 1) values
  ($r,$g,$b) = $encoder->as_RGB;

  # obtain RGB (0 <= R,G,B <= 255) values
  ($r255,$g255,$b255) = $encoder->as_RGB255;

  # obtain RGB hex (e.g. FF00FF - note no leading #)
  $hex = $encoder->as_RGBhex;

  # obtain HSV (0 <= H < 360, 0 <= S,V <= 1) values
  ($h,$s,$v) = $encoder->as_HSV;

  # change the encoding method
  $encoder->set_method("Color::TupleEncode::2Way");

  # see how many values this method accepts ($tuple_size = 2)
  $tuple_size = $encoder->get_tuple_size();

  # set the tuple with the new method and encode
  $encoder->set_tuple(1,2);

  ($r,$g,$b) = $encoder->as_RGB;

Use %options to define implementation and any parameters that control the encoding.

  %options = (-method=>"Color::TupleEncode::Baran");

  %options = (-method=>"Color::TupleEncode::Baran",
              -saturation=>{min=>0,max=>1,dmin=>0,dmax=>1});

A non-OO interface is also supported.

  # import functions explicitly
  use Color::TupleEncode qw(tuple_asRGB tuple_asRGB255 tuple_asHSV tuple_asRGBhex);

  # or import them all automatically
  use Color::TupleEncode qw(:all);

  # pass tuple and options just like with new()
  ($r,$g,$b) = tuple_asRGB(tuple=>[$a,$b,$c]);

  # specify options
  ($r,$g,$b) = tuple_asRGB(tuple=>[$a,$b,$c],options=>\%options)

  # specify method directly - note that ::2Way takes two values
  ($r,$g,$b) = tuple_asRGB(tuple=>[$a,$b],method=>"Color::TupleEncode::2Way");

  # tuple_asRGB255, tuple_asHSV and tuple_asRGBhex work analogously

COLOR ENCODINGS

Default Encoding

The default encoding method is due to Baran et al. (see "COLOR ENCODINGS"). This method encodes a 3-tuple (x,y,z) by first assigning a characteristic hue to each variable and then calculating a color based on the relative relationship of the values. The encoding is designed to emphasize the variable that is most different.

The default encoding is implemented in Color::TupleEncode::Baran.

Color::TupleEncode::2Way

This encoding converts a 2-tuple (x,y) to color. It is implemented in the module Color::TupleEncode::2Way.

If you would like to implement your own encoding, I suggest editing and extend this module. See "IMPLEMENTING AN ENCODING CLASS" for more details.

Other Encodings

Color::TupleEncode is designed to derive encoding functionality from utility modules, such as Color::TupleEncode::Baran. The utility modules implement the specifics of the tuple-to-color conversion and Color::TupleEncode does the housekeeping.

You can change the class by using -method in the %options hash passed to new()

  %options = (-method=>"Color::TupleEncode::2Way");

set the option directly

  $threeway->set_options(-method=>"Color::TupleEncode::2Way");

or pass the method name to new()

  Color::TupleEncode->new(method=>"Color::TupleEncode::2Way");

Note that when using the options hash, option names are prefixed by -. When passing arguments to new(), however, the - is not used.

EXAMPLES

Quick encoding

To encode a tuple with the default encoding scheme (Color::TupleEncode::Baran):

  use Color::TupleEncode qw(as_HSV as_RGBhex);

  my @tuple = (0.2,0.5,0.9);

  my @hsv = as_HSV(tuple=>\@tuple);    #  291 0.7 1.0
  my @rgb = as_RGB255(tuple=>\@tuple); #  230  77 255
  my $hex = as_RGBhex(tuple=>\@tuple); #  E64DFF

Encoding with options

Options control how individual encodings work. The Color::TupleEncode::Baran method supports changing the characteristic hues of each variable, min/max ranges for saturation and value and min/max ranges for the largest variable difference for saturation and value components.

  # change the characteristic hues
  my @hsv = as_HSV(tuple=>\@tuple,options=>{-ha=>60,-hb=>180,-hc=>300}); # 351 0.7 1.0

Using another implementation

  use Color::TupleEncode qw(as_HSV as_RGBhex);

  my @tuple = (0.2,0.5,0.9);

  my $method = "Color::TupleEncode::2Way";
  my @hsv   = tuple_asHSV(tuple=>\@tuple,method=>$method);    # 255 0.6 1.0
  my @rgb   = tuple_asRGB255(tuple=>\@tuple,method=>$method); # 102 140 255
  my @rgb   = tuple_asRGBhex(tuple=>\@tuple,method=>$method); # 668Cff

examples/example-3way

This is one of the example scripts in the examples/ directory. It shows how to use the 3-tuple encoding implemented by Color::TupleEncode::Baran

The example-3way takes a 3-tuple (or uses a random one) and reports its HSV, RGB and hex colors.

  # use a random tuple
  > examples/example-3way
  The 3-tuple 0.787 0.608 0.795 encodes as follows

  hue 125 saturation 0.186 value 1.000
  R 207 G 255 B 211
  hex CFFFD3

  # use a 3-tuple specified with -tuple
  > examples/example-3way -tuple 0.2,0.3,0.9
  The 3-tuple 0.200 0.300 0.900 encodes as follows

  hue 257 saturation 0.700 value 1.000
  R 128 G 77 B 255
  hex 804DFF

examples/examples-2way

This is one of the example scripts in the examples/ directory. It shows how to use the 2-tuple encoding implemented by Color::TupleEncode::2Way

The example-2way takes a 2-tuple (or uses a random one) and reports its HSV, RGB and hex colors.

  # use a random 2-tuple
  > examples/example-2way
  The 2-tuple 0.786 0.524 encodes as follows

  hue 240 saturation 0.440 value 0.126
  R 18 G 18 B 32
  hex 121220

  # use a 2-tuple specified with -tuple
  > examples/example-2way -tuple 0.2,0.9
  The 2-tuple 0.200 0.900 encodes as follows

  hue 40 saturation 0.167 value 0.422
  R 108 G 102 B 90
  hex 6C665A

examples/tuple2color

This script is much more flexible. It can read tuples from a file, or generate a matrix of tuples that span a given range. You can specify the implementation and options on the command line.

The script can also generate a PNG color chart of the kind seen at http://mkweb.bcgsc.ca/tupleencode/?color_charts.

By default tuple2color uses the 3-tuple encoding.

  # generate a matrix of tuples and report RGB, HSV and hex values
  > examples/tuple2color 
  abc 0 0 0 rgb 255 255 255 hsv 0 0 1 hex FFFFFF
  abc 0.2 0 0 rgb 255 204 204 hsv 0 0.2 1 hex FFCCCC
  abc 0.4 0 0 rgb 255 153 153 hsv 0 0.4 1 hex FF9999
  abc 0.6 0 0 rgb 255 102 102 hsv 0 0.6 1 hex FF6666
  abc 0.8 0 0 rgb 255 51 51 hsv 0 0.8 1 hex FF3333
  ...

  # specify range of matrix values (default is min=0, max=1, step=(max-min)/10)
  tuple2color -min 0 -max 1 -step 0.1

  # you can overwrite one or more matrix settings
  tuple2color -step 0.2

  # instead of using an automatically generated matrix, 
  # specify input data (tuples)
  tuple2color -data matrix_data.txt

  # specify how matrix entries should be sorted (default no sort)
  tuple2color -data matrix_data.txt -sortby a,b,c
  tuple2color -data matrix_data.txt -sortby b,c,a
  tuple2color -data matrix_data.txt -sortby c,a,b

  # specify implementation
  tuple2color -data matrix_data.txt -method Color::TupleEncode::Baran

  # specify options for Color::Threeway
  draw_color_char ... -options "-saturation=>{dmin=>0,dmax=>1}"

In addition, generate a PNG image of values and corresponding encoded colors.

  # draw color patch matrix using default settings
  tuple2color -draw

  # specify output image size
  tuple2color ... -width 500 -height 500

  # specify output file
  tuple2color ... -outfile somematrix.png

The 2-way and 3-way encoding color charts are bundled with this module, at examples/color-chart-*.png.

These charts were generated using examples/tuple2color as follows.

A large 2-tuple encoding chart with [a,b] in the range [0,2] sampling every 0.15.

  ./tuple2color -method "Color::TupleEncode::2Way"  \
                -min 0 -max 2 -step 0.15            \
                -outfile color-chart-2way.png       \
                -width 600 -height 1360             \
                -draw

A small 2-tuple encoding chart with [a,b] in the range [0,2] sampling every 0.3.

  ./tuple2color -method "Color::TupleEncode::2Way"  \
                -min 0 -max 2 -step 0.3             \
                -outfile color-chart-2way-small.png \
                -width 600 -height 430              \
                -draw

A large 3-tuple encoding chart with [a,b,c] in the range [0,1] sampling every 0.2.

  ./tuple2color -step 0.2                           \
                -outfile color-chart-3way.png       \
                -width 650 -height 1450             \
                -draw

A large 2-tuple encoding chart with [a,b,c] in the range [0,1] sampling every 1/3.

  ./tuple2color -step 0.33333333333                 \
                -outfile color-chart-3way-small.png \
                -width 650 -height 450              \
                -draw

SUBROUTINES/METHODS

new()

new( tuple => [ $a,$b,$c ] )

new( tuple => [ $a,$b,$c ], options => \%options)

new( tuple => [ $a,$b,$c ], method => $class_name)

new( tuple => [ $a,$b,$c ], method => $class_name, options => \%options)

Initializes the encoder object. You can immediately pass in a tuple, options and/or an encoding method. The method can be part of the option hash (as -method).

Options are passed in as a hash reference and the encoding method as the name of the module that implements the encoding. Two methods are available (Color::TupleEncode::Baran (default encoding) and Color::TupleEncode::2Way).

At any time if you try to pass in incorrectly formatted input (e.g. the wrong number of elements in a tuple, an option that is not understood by the encoding method), the module dies using confess.

You can write your own encoding method - see "IMPLEMENTING AN ENCODING CLASS" for details.

set_options( %options )

Define options that control how encoding is done. Each encoding method has its own set of options. For details, see "COLOR ENCODINGS".

Options are passed in as a hash and option names are prefixed with -.

  $encoder->set_options(-ha=>0,-hb=>120,-hc=>240);

$ok = has_option( $option_name )

Tests whether the current encoding scheme supports (and has set) the option $option_name.

If the method does not support the option, undef is returned.

If the method supports the option, but it is not set, 0 is returned.

If the method supports the option, and the option is set, 1 is returned.

%options = get_options()

$option_value = get_options( "-saturation" )

($option_value_1,$option_value_2) = get_options( qw(-saturation -value) )

Retrieve one or more (or all) option values. Options control how color encoding is done and are set by set_options() or during initialization.

If no option names are passed, a hash of all defined options (hash keys) and their values (hash values) is returned.

If one or more option names is passed, a list of corresponding values is returned.

set_tuple( @tuple )

set_tuple( \@tuple )

Define the tuple to encode to a color. Retrieve with get_tuple().

The tuple size must be compatible with the encoding method. You can check the required size with get_tuple_size().

@tuple = get_tuple()

Retrieve the current tuple, defind by set_tuple(@tuple).

$size = get_tuple_size()

Retrieve the size of the tuple for the current implementation. For example, the method by Baran et al. (see "COLOR ENCODINGS") uses three values as input, thus $size=3.

$method = get_method()

Retrieve the current encoding method. By default, this is Color::TupleEncode::Baran.

set_method( "Color::TupleEncode::2Way" )

Set the encoding method. By default, the method is Color::TupleEncode::Baran.

You can also set the method as an option

  $encoder->set_options(-method=>"Color::TupleEncode::2Way");

or at initialization

  Color::TupleEncode->new(method=>"Color::TupleEncode::2Way");

  Color::TupleEncode->new(options=>{-method=>"Color::TupleEncode::2Way"});

Note that when using the options hash, option names are prefixed by -. When passing arguments to new(), however, the - is not used.

($r,$g,$b) = as_RGB()

Retrieve the RGB encoding of the current tuple. The tuple is set by either set_tuple() or at initialization.

Each of the returned RGB component values are in the range [0,1].

If the tuple is not defined, then as_RGB(), this and other as_* methods return nothing (evaluates to false in all contexts).

as_RGB255()

Analogous to as_RGB() but each of the returned RGB component values are in the range [0,255].

$hex = as_RGBhex()

Analogous to as_RGB() but returned is the hex encoding (e.g. FF01AB) of the RGB color.

Note that the hex encoding does not have a leading #.

($h,$s,$v) = as_HSV()

Retrieve the HSV encoding of the current tuple. The tuple is set by either set_tuple() or at initialization.

Hue $h is in the range [0,360) and saturation $s and value $v in the range [0,1].

EXPORT

In addition to the object oriented interface, you can call these functions directly to obtain the color encoding. Note that any encoding options must be passed in each call.

($r,$g,$b) = tuple_asRGB( tuple => [$a,$b,$c])

($r,$g,$b) = tuple_asRGB( tuple => [$a,$b,$c], options => %options)

($r,$g,$b) = tuple_asRGB( tuple => [$a,$b,$c], method => $class_name)

($r,$g,$b) = tuple_asRGB( tuple => [$a,$b,$c], method => $class_name, options => %options)

($r,$g,$b) = tuple_asRGB255()

$hex = tuple_asRGBhex()

($h,$s,$v) = tuple_asHSV()

These functions work just like tuple_asRGB, but return the color in a different color space (e.g. RGB, HSV) or form (component or hex).

IMPLEMENTING AN ENCODING CLASS

Required Functions

It is assumed that the encoding utility class will implement the following functions.

_get_hue()
_get_saturation()
_get_value()

Encodings must be done from a tuple to HSV color space. HSV is a natural choice because it is possible to visually identify individual H,S,V components of a color (e.g. orage saturated dark). On the other hand, doing so in RGB is very difficult (what is the R,G,B decomposition of a dark desaturated orange?).

Each of these functions should be implemented as follows. For example, _get_saturation

  sub _get_saturation {
    # obtain the Color::TupleEncode object
    my $self = shift;
    # extract data tuple
    my (@tuple) = $self->get_tuple;
    my $saturation;
    ... now use @tuple to define $saturation
    return $saturation;
  }
_get_tuple_size()

This function returns the size of the tuple used by the encoding. You can implement this as follows,

  Readonly::Scalar our $TUPLE_SIZE => 3;

  sub _get_tuple_size {
    return $TUPLE_SIZE;
  }
_get_ok_options()
_get_default_options()

You must define a package variable @OPTIONS_OK, which lists all acceptable options for this encoding. Any options you wish to be set by default when this method is initially set should be in %OPTIONS_DEFAULT.

For example,

  Readonly::Array our @OPTIONS_OK      => 
      (qw(-ha -hb -hc -saturation -value));
  
  Readonly::Hash  our %OPTIONS_DEFAULT => 
      (-ha=>0,-hb=>120,-hc=>240,-saturation=>{dmin=>0,dmax=>1});

Two functions provice access to these variables

  sub _get_ok_options {
    return @OPTIONS_OK; 
  }

  sub _get_default_options {
    return %OPTIONS_DEFAULT;
  }

Using Your Implementation

See the example files with this distribution

  # uses Color::TupleEncode::2Way
  > examples/example-2way

  # uses Color::TupleEncode::Baran
  > examples/example-3way

of how to go about using your implementation.

For example, if you have created Color::TupleEncode::4Way, which encodes 4-tuples, then you would use it thus

  use Color::TupleEncode;
  use Color::TupleEncode::4Way;

  # set the method to your implementation
  $encoder = Color::TupleEncode->new(method=>"Color::TupleEncode::4Way");

  # set any options for your implementation
  $encoder->set-options(-option1=>1,-option2=>10)

  # encode
  ($h,$s,$v) = $encoder->as_HSV(1,2,3,4);

AUTHOR

Martin Krzywinski, <martin.krzywinski at gmail.com>

BUGS

Please report any bugs or feature requests to bug-color-tupleencode at rt.cpan.org, or through the web interface at http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Color-TupleEncode. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.

SUPPORT

You can find documentation for this module with the perldoc command.

    perldoc Color::TupleEncode

You can also look for information at:

SEE ALSO

Color::GraphicsObject for converting colors between color spaces.

Color::TupleEncode::Baran for the 3-tuple encoding (by Baran et al.).

Color::TupleEncode::2Way for the 2-tuple encoding (by Author).

ACKNOWLEDGEMENTS

For details about the color encoding, see

Color::TupleEncode::Baran

Encodes a 3-tuple to a color using the scheme described in

  Visualization of three-way comparisons of omics data
  Richard Baran Martin Robert, Makoto Suematsu, Tomoyoshi Soga and Masaru Tomita
  BMC Bioinformatics 2007, 8:72 doi:10.1186/1471-2105-8-72

This publication can be accessed at http://www.biomedcentral.com/1471-2105/8/72/abstract/

LICENSE AND COPYRIGHT

Copyright 2010 Martin Krzywinski.

This program is free software; you can redistribute it and/or modify it under the terms of either: the GNU General Public License as published by the Free Software Foundation; or the Artistic License.

See http://dev.perl.org/licenses/ for more information.