NAME

PDL::Graphics::Prima - an interactive plotting widget and library for PDL and Prima

SIMPLE SYNOPSIS

use PDL::Graphics::Prima::Simple;
use PDL;


# --( Super simple line and symbol plots )--

# Generate some data - a sine curve
my $x = sequence(100) / 20;
my $y = sin($x);

# Draw x/y pairs. Default x-value are sequential:
line_plot($y);        line_plot($x, $y);
circle_plot($y);      circle_plot($x, $y);
triangle_plot($y);    triangle_plot($x, $y);
square_plot($y);      square_plot($x, $y);
diamond_plot($y);     diamond_plot($x, $y);
X_plot($y);           X_plot($x, $y);
cross_plot($y);       cross_plot($x, $y);
asterisk_plot($y);    asterisk_plot($x, $y);

# Sketch the sine function for x initially from 0 to 10:
func_plot(0 => 10, \&PDL::sin);


# --( Super simple histogram )--

# PDL hist method returns x/y data
hist_plot($y->hist);
my ($bin_centers, $heights) = $y->hist;
hist_plot($bin_centers, $heights);
# Even simpler, if of limited use:
hist_plot($heights);


# --( Super simple matrix plots )--

# Generate some data - a wavy pattern
my $image = sin(sequence(100)/10)
            + sin(sequence(100)/20)->transpose;

# Generate a greyscale image:
matrix_plot($image);  # smallest is white
imag_plot($image);    # smallest is black

# Set the x and y coordinates for the image boundaries
#            left, right,  bottom, top
matrix_plot([ 0,     1  ], [ 0,     2 ],  $image);
imag_plot(  [ 0,     1  ], [ 0,     2 ],  $image);


# --( More complex plots )--

# Use the more general 'plot' function for
# multiple datasets and more plotting features:
my $colors = pal::Rainbow()->apply($x);
plot(
    -lines         => ds::Pair($x, $y
        , plotType => ppair::Lines
    ),
    -color_squares => ds::Pair($x, $y + 1
        , colors   => $colors,
        , plotType => ppair::Squares(filled => 1)
    ),
    
    x => { label   => 'Time' },
    y => { label   => 'Sine' },
);

WIDGET SYNOPSIS

use PDL;
use Prima qw(Application);
use PDL::Graphics::Prima;

my $t_data = sequence(6) / 0.5 + 1;
my $y_data = exp($t_data);

my $wDisplay = Prima::MainWindow->create(
    text  => 'Graph Test',
    size  => [300, 300],
);

$wDisplay->insert('Plot',
    -function => ds::Func(\&PDL::exp, color => cl::Blue),
    -data => ds::Pair($t_data, $y_data, color => cl::Red),
    pack => { fill => 'both', expand => 1},
);

run Prima;

IF YOU ARE NEW

If you are new to PDL::Graphics::Prima, you should begin by reading the documentation for PDL::Graphics::Prima::Simple. This module provides a simplified interface for quickly dashing off a few plots and offers stepping stones to create more complex plots. Depending on your plotting needs, you may not need anything more complicated than PDL::Graphics::Prima::Simple. However, PDL::Graphics::Prima offers much greater flexibility and interactivity than the options available in the Simple interface, so once you feel comfortable, you should come back to this manual page and learn how to create and utilize Plot widgets in conjunction with the Prima GUI toolkit.

DESCRIPTION

PDL::Graphics::Prima is a plotting interface for creating and exploring 2D data visualizations. The core of this interace is a Plot widget that can be incorporated into Prima applications.

Properties

title, titleSpace

Sets or gets the string that contains the title and the space allocated for the title at the top of the plot.

dataSets

This either sets or returns the data sets. The data sets are held in a tied anonymous hash that you directly manipulate. In order to add a new dataset, you don't have to make a second call to dataSets; you can simply modify the anonymous hash in place using standard Perl hash manipulation functions. Since the hash is actually tied, datasets that you add will be validated as you add them.

Events

You can send notifications and hook callbacks for the following events:

ChangeTitle

Called when the title or titleSpace gets changed

Replot

Called when the widget needs to replot

ChangeData

Called when the dataSet container changes (not the datasets themselves, but the whole container).

RESPONSIBILITIES

The Plot object itself has to coordinate a number of sub-systems in order to get a functioning plot. As these responsiblities are not always clear even to their author, here is a list of what the plot is responsible for handling.

knowing the plot title

Although the axes are responsible for knowing the axis labels, the plot itself is responsible for knowing the plot title.

initiating drawing operations

The drawing of the axes, data, and plot title are all coordinated, ultimately, by the plot object.

initiating autoscaling

Autoscaling for either of the axes is initiated by a call to the plot object's compute_min_max_for, which computes the minima and maxima for a given axis. Most of the calculations necessary for this operation are performed by the dataset and the underlying plotTypes, but they are coordinated and synthesized by the plot object.

managing the dataset container

The plot does not manage the datasets directly, but it owns the dataset container that is responsible for this.

handling user interaction

All user interaction (which at the moment is limited to mouse interaction) is handled by the plot object. Drag and zoom events ultimately lead to changes in the axes' minima and maxima (the axes are responsible for these pieces of information), but these changes are initiated through the plot object.

Many things are not the responsiblity of the plot object but are instead handled by other objects, usually held as objects within the plot object itself.

tick and axis details

All axis and tick details, including minima and maxima, scaling, tick mark locations, axis labels, and conversion from real x and y data values to pixel offsets are handled by the axis objects.

managing datasets or plotTypes

The datasets are managed by the dataset collection hashref defined in PDL::Graphics::Prima::DataSet. Any access to the datasets (outside of declaring them directly in the constructor, which is a special-case) is managed throug the dataSet collection. Any access to the specific plot types are themselves handled by the datasets themselves.

TODO

Idea: set the ability to buffer replot notifications, so that you can fiddle with datasets without triggering a replot. That should improve performance when multiple datasets are dynamically added and removed. Then again, this is likely to be a problem only with very large datasets.

This is not a perfect plotting library. Here are some of the particularly annoying issues with it, which I hope to resolve:

adjustable right and bottom margins means mouse scroll-wheel action doesn't work exactly as advertised

something's messed up with the x-ticks, and sometimes the left x-tick does not line-up with the edge of the horizontal axis line.

linear tick scaling can switch the 'natural' major and minor ticks just by moving, which makes it seem jittery. The function for determining the major and minor ticks should be simplified and based only on the scale of interest.

singular properties (like color, as opposed to colors) do not Do What You Mean. With PlotTypes, they often don't do anything at all. Although I could resolve this problem in this library, I would rather address this in PDL::Drawing::Prima.

Shouldn't singular names => scalars, plural names => piddles be consistent across the board? It's not, at least not with the plotTypes.

multiple axes. In the constructor, any property that starts with x would be an x-axis (x1, x2, etc). You would have to specify an axes with a dataset, though the default would be the first axis when sorted asciibetically. Axes would have properties regarding if they are drawn on the top, the bottom, both, etc, and whether their tick labels are drawn on the top, bottom, etc.

I am very proud of the automatic scaling. There are two drawbacks. (1) It's complicated and not yet well documented. That needs fixing. (2) It could be even more awesome. For example, it would be great to be able to specify a minimum pixel padding, as well as an extra pixel padding. This would simply effect how collate_min_max_for_many works and should be a snap to implement.

Handle the titleSpace in a more intelligent way

AUTHOR

David Mertens (dcmertens.perl@gmail.com)

SEE ALSO

Both the Perl Data Language and the Prima GUI Toolkit are amazing and this module would have no reason for existence without both of them.

This module serves as the motivation for PDL::Drawing::Prima, and also would be unable to function with any efficiency without it.

Other 2D plotting options include PDL::Graphics::PGPLOT, PDL::Graphics::PLplot, PDL::Graphics::Gnuplot, PDL::Graphics::Asymptote, and many others. Search CPAN for more.

For 3D plotting, see PDL::Graphics::TriD.

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::Internals

A dumping ground for my partial documentation of some of the more complicated stuff. It's not organized, so you probably shouldn't read it.

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::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

LICENSE AND COPYRIGHT

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-2012 Northwestern University.

This module's documentation are copyright (c) 2011-2012 David Mertens.

All rights reserved.

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