NAME

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

VERSION

Version 0.1

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});

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.

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.