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

NAME

PDL::Graphics::Prima::Palette - a set of palettes for the Prima graph widget

DESCRIPTION

Suppose you want to use color to convey some meaningful value. For example, you want the color to represent the topography of a landscape, darker is lower, lighter is higher. In that case, you need a mapping from a height to a color, i.e. from a scalar value to a color. This is what palettes provide.

If all you need is basic palette, you can use one of the palette builders provided below. That said, creating custom color palettes, when you have some idea of what you're doing and a simple means for doing so, is a lot of fun. This, for example, creates a palette that runs from black to red. You could just use pal::BlackToHSV, but what's the fun in that?

 my $palette = PDL::Graphics::Prima::Palette->new(
     apply => sub {
         my $data = shift;
         my ($min, $max) = $data->minmax;
         return floor((($data - $min) / ($max - $min)) * 255) * 0x10000;
     }
 );

Applying the palette to some data simply calls the subref that your provided earlier:

 my $colors = $palette->apply($some_data);

Using this with a standard palette builder is pretty easy, too:

 my $colors = pal::Rainbow->apply($some_data);

And, you can provide the palette to customize how pgrid::Matrix colorizes its data:

 my $x = sequence(100)/10 + 0.1;
 my $y = $x->sin + $x->grandom / 10;
 plot(
     -data => ds::Grid( $y,
         plotType => pgrid::Matrix(palette => $palette),
         bounds => [0, 0, 1, 1],
     )
 );

new

Accepts key/value pairs. The only required key is the apply key, which should have a coderef that accepts a data piddle and performs the data-to-color conversion, returning a piddle of Prima colors. Note that when using the HSVRange palette described below, the apply key is NOT mandatory.

If this palette is being rendered as the plot-wide color map, there is a wide variety of properties that let you tweak how it is drawn. The label indicates a string that will be drawn above the color bar. You can specify a boolean value for boxed which indicates whether or not to enclose the color bar in a box. There are then a large collection of SizeSpecs that control the exact positioning and sizes of the color bar, its tick marks, and the tick mark labels. These include:

outer_margin

the space between the edge of the plot and the edge of the widest tick label

tick_label_padding

the space between the labels and the end of the tick mark

tick_size

the length of the tick mark

tick_padding

the space between the color bar and the end of the tick mark

bar_width

the width of the color bar

inner_margin

the space between the color bar and the outer edge of the plotting space

top_margin

the space between either the figure title or the top of the figure and the top of the color bar or (if there is a label) the color map's label

label_padding

the space between the bottom of the label and the top of the color bar, if the label is present (this is ignored if there is no label text)

bottom_margin

the space between the bottom edge of the figure and the bottom of the color bar

Finally, there are three additional keys that are not usable by this basic palette, but are usable by derived palette classes. The min and max properties can be used to explicitly set the minimum and maximum values to be used in the scaling. This is useful when multiple datasets are using the same palette and you want consistency in the color scaling. If you do not set these you will get automatic scaling, but if you want to change them from a fixed number back to autoscaling, you can use the lm::Auto value that is also used to tell the x- and y-axes to resume autoscaling. The last key of interest is the badval_color key, which provides a Prima color to use when the system encounters bad data. The default value is cl::Brown.

Note that any colors that fall outside of explicitly specified minimum and maximum values have no guarantees about their rendering. Eventually it would be good to provide keys toohigh_color and toolow_color, just like badval_color. However, the exact rendering of those on the visualization still needs to be worked out

generate_size_specs_for_canvas

This method takes a single canvas as an argument and generates a hashref containing SizeSpec objects for all of the size specs for the Palette. But if you need access to those size specs, you probably don't want to use this. Use size_specs_for_canvas instead, which should be a little faster than this because it caches for the common case of SizeSpecs for the palette's plot widget.

size_specs_for_canvas

This method takes a single canvas as an argument and returns a hashref containing SizeSpec objects for all of the size specs for the Palette. Unlike generate_size_specs_for_canvas, this uses cached SizeSpecs for the plot widget and so is usually faster.

scaling

Every palette knows its scaling. At the time of writing that's either linear or logarithmic. The default scaling is linear.

apply

Every palette knows how to apply itself to its data. The apply function returns a piddle of Prima color values given a piddle of scalar values. After calling the pallete's apply subref, all points that were previously bad in the given data are marked with the badval_color.

boxed

Getter/setter for the boxed property. If this is a color map, setting this will trigger a redraw of the plot. If this is not a color map, then setting this has no effect on anything.

draw

Draws the palette on the associated widget.

set_autoscaling_minmax

Sets or clears the values to be used as the minimum and maximum when they are set to lm::Auto.

minmax

Returns the minimum and maximum values that will be used by the palette. This optionally takes a single argument, the data to be transformed. If either of the explicit min or max values are set to lm::Auto, this checks to see if an autoscaling minmax pair has been set and uses those in place of lm::Auto. If there is no autoscaling minmax pair, then this queries the data for its min and/or max and uses those. If the method gets this far but you did not pass data to be transformed, it croaks saying

  Requested palette minmax but none specified,
  autoscaling minmax not set, and no data given

get_tick_label_width

Computes the width needed to draw all the palette tick labels. This dynamically generates the list of labels and computes the width of the widest one. Takes an optional argument for the canvas upon which to draw, but defaults to the current widget if none is given.

Because this needs to compute text widths, this can only be called on a palette that has been attached to a widget.

get_width

Computes the total width of the given palette. This can only be called on a palette that has been attached to a widget and for which the minimum and maximum data values have been articulated.

Special Palettes

This module provides many ready-made palettes with short-name constructors in the pal namespace.

pal::Rainbow

Runs from red->orange->yellow->green->blue->purple in ascending order.

pal::RainbowSV

Runs from red->orange->yellow->green->blue->purple in ascending order. The two arguments it accepts are the saturation and value, which it holds uniformly. This makes it much easier to create palettes that can be easily seen against a white background. For example, the yellow from this palette is much eaiser to see against a white background than the yellow from pal::Rainbow:

 pal::RainbowSV(1, 0.8)
pal::BlackToWhite

Larger values are white, smaller values are black. The optional argument is the gamma exponent correction value, which should be positive. Typically, gamma exponents are near 0.5.

pal::WhiteToBlack

Larger values are black, smaller values are white. The optional argument is the gamma exponent correction value, which should be positive. Typically, gamma exponents are near 0.5.

pal::WhiteToHSV

Smaller values are closer to white, larger values are closer to the color indicated by the HSV values that you specify, which are supplied to the function as three different scalars. The first three arguments are hue, saturation, and value. The optional fourth value is a gamma correction exponent.

For example:

 my $white_to_red = pal::WhiteToHSV(0, 1, 1);
 my $gamma_white_to_red = pal::WhiteToHSV(0, 1, 1, 0.8);
pal::BlackToHSV

Like WhiteToHSV, but smaller values are closer to black instead of white.

pal::HSVrange

Maps data in ascending order from the start to the stop values in hue, saturation, and value. You can specify the initial and final hue, saturation, and value in one of two ways: (1) a pair of three-element arrayrefs/piddles with the initial and final hsv values, or (3) a set of key/value pairs describing the initial and final hue, saturation and value. You can also specify data min and max. Any data that falls below the min or above the max will be represented with the closest min or max color. This is particularly helpful when you need to coordinate the min and max of multiple palettes.

For example, this creates a palette that runs from red (H=360) to blue (H=240):

 my $blue_to_red = pal::HSVrange([360, 1, 1] => [240, 1, 1]);

If you know the Prima name of your color, you can use the conversion functions provided by PDL::Drawing::Prima::Utils to build an HSV range. This example produces a palette from blue to red:

 my $blue_hsv = pdl(cl::LightBlue)->color_to_rgb->rgb_to_hsv;
 my $red_hsv = pdl(cl::LightRed)->color_to_rgb->rgb_to_hsv;
 my $blue_to_red = pal::HSVrange($blue_hsv, $red_hsv);

The final means for specifying a range in HSV space is to provide key/value pairs that describe your initial and final points in HSV space. You can also specify a non-unitary gamma correction exponent. For example, to go from blue to red with a gamma of 0.8, you could say:

 my $blue_to_red = pal::HSVrange(
       h_start => 240,
       s_start => 1,
       v_start => 1,
       h_stop  => 360,
       s_stop  => 1,
       v_stop  => 1,
       gamma   => 0.8,
   );

However, you do not need to provide all of these values. Any key that you do not supply will use a default value:

 Key       Default
 -----------------
 h_start   0
 s_start   1
 v_start   1
 h_stop    360
 s_stop    1
 v_stop    1
 gamma     1

So the blue-to-red palette, without a gamma correction, could be specified as:

 my $blue_to_red = pal::HSVrange(
     h_start => 240, h_stop => 360,
 );

AUTHOR

David Mertens (dcmertens.perl@gmail.com)

ADDITIONAL MODULES

Here is the full list of modules in this distribution:

PDL::Graphics::Prima

Defines the Plot widget for use in Prima applications

PDL::Graphics::Prima::Axis

Specifies the behavior of axes (but not the scaling)

PDL::Graphics::Prima::DataSet

Specifies the behavior of DataSets

PDL::Graphics::Prima::Limits

Defines the lm:: namespace

PDL::Graphics::Prima::Palette

Specifies a collection of different color palettes

PDL::Graphics::Prima::PlotType

Defines the different ways to visualize your data

PDL::Graphics::Prima::ReadLine

Encapsulates all interaction with the Term::ReadLine family of modules.

PDL::Graphics::Prima::Scaling

Specifies different kinds of scaling, including linear and logarithmic

PDL::Graphics::Prima::Simple

Defines a number of useful functions for generating simple and not-so-simple plots

PDL::Graphics::Prima::SizeSpec

Compute pixel distances from meaningful units

LICENSE AND COPYRIGHT

Unless otherwise stated, all contributions in code and documentation are copyright (c) their respective authors, all rights reserved.

Portions of this module's code are copyright (c) 2011 The Board of Trustees at the University of Illinois.

Portions of this module's code are copyright (c) 2011-2013 Northwestern University.

Portions of this module's code are copyright (c) 2013-2014 Dickinson College.

This module's documentation is copyright (c) 2011-2014 David Mertens.

This module is free software; you can redistribute it and/or modify it under the same terms as Perl itself.