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 easier 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.