NAME

Chart::Colors - Perl extension to return an endless stream of new distinct RGB colours codes (good for coloring any number of chart lines)

SYNOPSIS

#!/usr/bin/perl -w
  
use Chart::Colors;

my $colors = new Chart::Colors();
my $nextcolor_hex=$colors->Next('hex');	# Get an HTML-Style answer, like F85099 (put a # in front to use in HTML, i.e. #F85099)
my($r,$g,$b)=$colors->Next('rgb');		# Get red, green, and blue ints separately, like (255,123,88)
my($h,$s,$v)=$colors->Next('hsv');		# Get hue, saturation, and brightness

DESCRIPTION

This module outputs an infinte sequence of visually distinct different colours.

It is useful for colorizing the lines on charts etc.

EXAMPLE

# perl -MChart::Colors -e '$c=new Chart::Colors(); for(my $i=0;$i<5;$i++) { print "$i\t( " . join(", ",$c->Next()) . " )\n";}; print "#" . $c->Next("hex") . "\n"; print join("|", $c->Next("hsv")) . "\n"; ' 
0       ( 204, 81, 81 )
1       ( 127, 51, 51 )
2       ( 81, 204, 204 )
3       ( 51, 127, 127 )
4       ( 142, 204, 81 )
#597f33
0.75|0.6|0.8

EXPORT

None by default.

Notes

new

Usage is

my $colors = new Chart::Colors();

Next

Returns a colour code in hexadecimal ('hex'), red, green, blue ('rgb') or hue, saturation, and brightnes ('hsv') format.

Usage is

my $nextcolor_hex = $colors->Next('hex');

or

my($r,$g,$b)=$colors->Next('rgb');

or

my($h,$s,$v)=$colors->Next('hsv');	

hsv_to_rgb

my($r,$g,$b)=$this->hsv_to_rgb($h,$s,$v);

AUTHOR

This module was written by Chris Drake cdrake@cpan.org, and based on https://stackoverflow.com/questions/24852345/hsv-to-rgb-color-conversion

COPYRIGHT AND LICENSE

Copyright (c) 2019 Chris Drake. All rights reserved.

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself, either Perl version 5.18.2 or, at your option, any later version of Perl 5 you may have available.

# from https://stackoverflow.com/questions/24852345/hsv-to-rgb-color-conversion
def hsv_to_rgb(h, s, v):
    if s == 0.0: v*=255; return (v, v, v)
    i = int(h*6.) # XXX assume int() truncates!
    f = (h*6.)-i; p,q,t = int(255*(v*(1.-s))), int(255*(v*(1.-s*f))), int(255*(v*(1.-s*(1.-f)))); v*=255; i%=6
    if i == 0: return (v, t, p)
    if i == 1: return (q, v, p)
    if i == 2: return (p, v, t)
    if i == 3: return (p, q, v)
    if i == 4: return (t, p, v)
    if i == 5: return (v, p, q)

# !/usr/bin/env python3.3

from sys import argv import colorsys import itertools from fractions import Fraction

def zenos_dichotomy(): for k in itertools.count(): yield Fraction(1,2**k) # yeild is like return, except next call continues

def getfracs(): """ [Fraction(0, 1), Fraction(1, 2), Fraction(1, 4), Fraction(3, 4), Fraction(1, 8), Fraction(3, 8), Fraction(5, 8), Fraction(7, 8), Fraction(1, 16), Fraction(3, 16), ...] [0.0, 0.5, 0.25, 0.75, 0.125, 0.375, 0.625, 0.875, 0.0625, 0.1875, ...] """ yield 0 for k in zenos_dichotomy(): i = k.denominator # [1,2,4,8,16,...] for j in range(1,i,2): # start,stop,step yield Fraction(j,i)

bias = lambda x: (math.sqrt(x/3)/Fraction(2,3)+Fraction(1,3))/Fraction(6,5) # can be used for the v in hsv to map linear values 0..1 to something that looks equidistant

def genhsv(h): for s in [Fraction(6,10)]: # optionally use range for v in [Fraction(8,10),Fraction(5,10)]: # could use range too yield (h, s, v) # use bias for v here if you use range

genrgb = lambda x: colorsys.hsv_to_rgb(*x)

flatten = itertools.chain.from_iterable

gethsvs = lambda: flatten(map(genhsv,getfracs()))

getrgbs = lambda: map(genrgb, gethsvs())

def genhtml(x): uint8tuple = map(lambda y: int(y*255), x) return "{},{},{}".format(*uint8tuple)

gethtmlcolors = lambda: map(genhtml, getrgbs())

if __name__ == "__main__": print(list(itertools.islice(gethtmlcolors(), int(argv[1]))))

# print(list(itertools.islice(gethtmlcolors(), int(argv[1])))) # print(list(itertools.islice(gethtmlcolors(), 10)))