| PDL::Graphics::Simple(3pm) | User Contributed Perl Documentation | PDL::Graphics::Simple(3pm) |
PDL::Graphics::Simple - Simple backend-independent plotting for PDL
# Simple interface - throw plots up on-screen, ASAP
use PDL::Graphics::Simple;
imag $a; # Display an image PDL
imag $a, 0, 300; # Display with color range
line $rrr, $fit; # Plot a line
points $rr, $sec; # Plot points
hold; # Hold graphics so subsequent calls overplot
line $rrr, $fit; # Overplot a line in a contrasting color
release; # Release graphics
# Object interface - simple plotting, to file or screen
$w = pgswin( size=>[8,4], multi=>[2,2] ); # 2x2 plot grid on an 8"x4" window
$w = pgswin( size=>[1000,1000,'px'], output=>'plot.png' ); # output to a PNG
$w->plot( with=>'points', $rr, $sec, with=>'line', $rrr, $fit,
{title=>"Points and fit", xlabel=>"Abscissa", ylabel=>"Ordinate"});
PDL can plot through a plethora of external plotting modules. Each module tends to be less widely available than Perl itself, and to require an additional step or two to install. For simple applications ("throw up an image on the screen", or "plot a curve") it is useful to have a subset of all plotting capability available in a backend-independent layer. PDL::Graphics::Simple provides that capability.
PDL::Graphics::Simple implements all the functionality used in the PDL::Book examples, with identical syntax. It also generalizes that syntax - you can use ::Simple graphics, with slight syntactical differences, in the same manner that you would use any of the engine modules. See the Examples below for details.
The plot you get will always be what you asked for, regardless of which plotting engine you have installed on your system.
Only a small subset of PDL's complete graphics functionality is supported -- each individual plotting module has unique advantages and functionality that are beyond what PDL::Graphics::Simple can do. Only 2-D plotting is supported. For 3-D plotting, use PDL::Graphics::Gnuplot or PDL::Graphics::TriD directly.
When plotting to a file, the file output is not guaranteed to be present until the plot object is destroyed (e.g. by being undefed or going out of scope).
PDL::Graphics::Simple currently supports most of the planned functionality. It is being released as a beta test to determine if it meets users' needs and gain feedback on the API -- so please give feedback!
PDL::Graphics::Simple includes support for the following graphics engines. Additional driver modules can be loaded dynamically; see "register", below. Each of the engines has unique capabilities and flavor that are not captured in PDL::Graphics::Simple - you are encouraged to look at the individual modules for more capability!
Gnuplot is an extremely richly featured plotting package that offers markup, rich text control, RGB color, and 2-D and 3-D plotting. Its output is publication quality. It is supported on POSIX systems, MacOS, and Microsoft Windows, and is available from most package managers.
PGPLOT is venerable and nearly as fully featured as Gnuplot for 2-D plotting. It lacks RGB color output. It does have rich text control, but uses simple plotter fonts that are generated internally. It is supported on MacOS and POSIX, but is not as widely available as Gnuplot.
PLplot is a moderately full featured plotting package that generates publication quality output with a simple high-level interface. It is supported on MacOS and POSIX.
Prima is based around a widget paradigm that enables complex interaction with data in real-time, and it is highly optimized for that application. It is not as mature as the other platforms, particularly for static plot generation to files. This means that PDL::Graphics::Simple does not play to its considerable strengths, although Prima is serviceable and fast in this application. Please run the Prima demo in the perldl shell for a better sample of Prima's capabilities.
PDL::Graphics::Simple can be called using plot-atomic or curve-atomic plotting styles, using a pidgin form of calls to any of the main modules. The examples are divided into Book-like (very simple), PGPLOT-like (curve-atomic), and Gnuplot-like (plot-atomic) cases.
There are three main styles of interaction with plot objects that PDL::Graphics::Simple supports, reflective of the pre-existing modules' styles of interaction. You can mix-and-match them to match your particular needs and coding style. Here are examples showing convenient ways to call the code.
For the very simplest actions there are non-object-oriented shortcuts. Here are some examples of simple tasks, including axis labels and plot titles. These non-object-oriented shortcuts are useful for display with the default window size. They make use of a package-global plot object.
The non-object interface will keep using the last plot engine you used successfully. On first start, you can specify an engine with the environment variable "PDL_SIMPLE_ENGINE". As of 1.011, only that will be tried, but if you didn't specify one, all known engines are tried in alphabetical order until one works.
The value of "PDL_SIMPLE_ENGINE" should be the "shortname" of the engine, currently:
use PDL::Graphics::Simple; $x = xvals(51)/5; $y = $x**3; $y->line; line( $x, $y ); line( $x, $y, {title=>"My plot", ylabel=> "Ordinate", xlabel=>"Abscissa"} );
$y->bins;
bins($y, {title=>"Bin plot", xl=>"Bin number", yl=>"Count"} );
$y->points;
points($y, {title=>"Points plot"});
line( $y, { log=>'y' } ); # semilog
line( $y, { log=>'xy' } ); # log-log
$im = 10 * sin(rvals(101,101)) / (10 + rvals(101,101));
imag $im; # Display image
imag $im, 0, 1; # Set lower/upper color range
points($x, $y, {logx=>1});
hold;
line($x, sqrt($y)*10);
release;
imag $im, {justify=>1}
points($x, $y, {justify=>1});
erase();
More functionality is accessible through direct use of the PDL::Graphics::Simple object. You can set plot size, direct plots to files, and set up multi-panel plots.
The constructor accepts window configuration options that set the plotting environment, including size, driving plot engine, output, and multiple panels in a single window.
For interactive/display plots, the plot is rendered immediately, and lasts until the object is destroyed. For file plots, the file is not guaranteed to exist and be correct until the object is destroyed.
The basic plotting method is "plot". "plot" accepts a collection of arguments that describe one or more "curves" (or datasets) to plot, followed by an optional plot option hash that affects the entire plot. Overplotting is implemented via plot option, via a held/released state (as in PGPLOT), and via a convenience method "oplot" that causes the current plot to be overplotted on the previous one.
Plot style (line/points/bins/etc.) is selected via the "with" curve option. Several convenience methods exist to create plots in the various styles.
use PDL::Graphics::Simple; $x = xvals(51)/5; $y = $x**3; $win = pgswin(); # plot to a default-shape window $win = pgswin( size=>[4,3] ); # size is given in inches by default $win = pgswin( size=>[10,5,'cm'] ); # You can feed in other units too $win = pgswin( out=>'plot.ps' ); # Plot to a file (type is via suffix) $win = pgswin( engine=>'gnuplot' ); # Pick a particular plotting engine $win = pgswin( multi=>[2,2] ); # Set up for a 2x2 4-panel plot
$win->plot( with=>'line', $x, $y, {title=>"Simple line plot"} );
$win->plot( with=>'errorbars', $x, $y, sqrt($y), {title=>"Error bars"} );
$win->plot( with=>'circles', $x, $y, sin($x)**2 );
# All at once
$win->plot( with=>'line', $x, $y, with=>'circles', $x, $y/2, sqrt($y) );
# Using oplot (IDL-style; PLplot-style)
$win->plot( with=>'line', $x, $y );
$win->oplot( with=>'circles', $x, $y/2, sqrt($y) );
# Using object state (PGPLOT-style)
$win->line( $x, $y );
$win->hold;
$win->circles( $x, $y/2, sqrt($y) );
$win->release;
PDL::Graphics::Simple::show
"show" lists the supported engines and a one-line synopsis of each.
$w = pgswin( %opts );
"pgswin" is a constructor that is exported by default into the using package. Calling pgswin(%opts) is exactly the same as calling "PDL::Graphics::Simple->new(%opts)".
$w = PDL::Graphics::Simple->new( %opts );
"new" is the main constructor for PDL::Graphics::Simple. It accepts a list of options about the type of window you want:
NOTE for multiplotting: "oplot" does not work and will cause an exception. This is a limitation imposed by Gnuplot.
$w = PDL::Graphics::Simple->new( %opts ); $w->plot($data);
"plot" plots zero or more traces of data on a graph. It accepts two kinds of options: plot options that affect the whole plot, and curve options that affect each curve. The arguments are divided into "curve blocks", each of which contains a curve options hash followed by data.
If the last argument is a hash ref, it is always treated as plot options. If the first and second arguments are both hash refs, then the first argument is treated as plot options and the second as curve options for the first curve block.
Plot options:
This controls whether and where a plot legend should be placed. If you set it, you supply a combination of 't','b','c','l', and 'r': indicating top, bottom, center, left, right position for the plot legend. For example, 'tl' for top left, 'tc' for center top, 'c' or 'cc' for dead center. If left unset, no legend will be plotted. If you set it but don't specify a position (or part of one), it defaults to top and left.
If you supply even one 'key' curve option in the curves, legend defaults to the value 'tl' if it isn't specified.
Curve options:
Curve types supported
For RGB images, the numerical values need to be in the range 0-255, as they are interpreted as 8 bits per plane colour values. E.g.:
$w = pgswin(); # plot to a default-shape window
$w->image( pdl(xvals(9,9),yvals(9,9),rvals(9,9))*20 );
# or, from an image on disk:
$image_data = rpic( 'my-image.png' )->mv(0,-1); # need RGB 3-dim last
$w->image( $image_data );
If you have a 2-D field of values that you would like to see with a heatmap:
use PDL::Graphics::ColorSpace;
sub as_heatmap {
my ($d) = @_;
my $max = $d->max;
die "as_heatmap: can't work if max == 0" if $max == 0;
$d /= $max; # negative OK
my $hue = (1 - $d)*240;
$d = cat($hue, pdl(1), pdl(1));
(hsv_to_rgb($d->mv(-1,0)) * 255)->byte->mv(0,-1);
}
$w->image( as_heatmap(rvals 300,300) );
use PDL::Transform::Cartography;
use PDL::Graphics::Simple qw(pgswin);
$coast = earth_coast()->glue( 1, scalar graticule(15,1) );
$w = pgswin();
$w->plot(with => 'polylines', $coast->clean_lines);
$w = PDL::Graphics::Simple->new( %opts ); $w->plot($data); $w->oplot($more_data);
"oplot" is a convenience interface. It is exactly equivalent to "plot" except it sets the plot option "oplot", so that the plot will be overlain on the previous one.
# Object-oriented convenience $w = PDL::Graphics::Simple->new( % opts ); $w->line($data); # Very Lazy Convenience $a = xvals(50); lines $a; $im = sin(rvals(100,100)/3); imag $im; imag $im, 0, 1, {title=>"Bullseye?", j=>1};
"line", "points", and "image" are convenience interfaces. They are exactly equivalent to "plot" except that they set the default "with" curve option to the appropriate plot type.
"imag" is even more DWIMMy for PGPLOT users or PDL Book readers: it accepts up to three non-hash arguments at the start of the argument list. The second and third are taken to be values for the "crange" plot option.
"cont" resembles the PGPLOT function.
use PDL::Graphics::Simple qw/erase hold release/; line xvals(10), xvals(10)**2 ; sleep 5; erase;
"erase" removes a global plot window. It should not be called as a method. To remove a plot window contained in a variable, undefine it.
use PDL::Graphics::Simple; line xvals(10); hold; line xvals(10)**0.5;
Causes subsequent plots to be overplotted on any existing one. Called as a function with no arguments, "hold" applies to the global object. Called as an object method, it applies to the object.
use PDL::Graphics::Simple; line xvals(10); hold; line xvals(10)**0.5; release; line xvals(10)**0.5;
Releases a hold placed by "hold".
PDL::Graphics::Simple::register( \%description );
This is the registration mechanism for new driver methods for "PDL::Graphics::Simple". Compliant drivers should announce themselves at compile time by calling "register", passing a hash ref containing the following keys:
That value will only change when the API changes, allowing the modules to be released independently, rather than with every version of PDL::Graphics::Simple as up to 1.010.
PDL::Graphics::Simple defines an object that represents a plotting window/interface. When you construct the object, you can either specify a backend or allow PDL::Graphics::Simple to find a backend that seems to work on your system. Subsequent plotting commands are translated and passed through to that working plotting module.
PDL::Graphics::Simple calls are dispatched in a two-step process. The main module curries the arguments, parsing them into a regularized form and carrying out DWIM optimizations. The regularized arguments are passed to implementation classes that translate them into the APIs of their respective plot engines. The classes are very simple and implement only a few methods, outlined below. They are intended only to be called by the PDL::Graphics::Simple driver, which limits the need for argument processing, currying, and parsing. The classes are thus responsible only for converting the regularized parameters to plot calls in the form expected by their corresponding plot modules.
PDL::Graphics::Simple works through a call-and-dispatch system rather than taking full advantage of inheritance. That is for two reasons: (1) it makes central control mildly easier going forward, since calls are dispatched through the main module; and (2) it makes the non-object-oriented interface easier to implement since the main interface modules are in one place and can access the global object easily.
Each interface module supports the following methods:
check
"check" attempts to load the relevant engine module and test that it is working. In addition to returning a boolean value indicating success if true, it registers its success or failure in the main $mods hash, under the "ok" flag. If there is a failure that generates an error message, the error is logged under the "msg" flag.
"check" accepts one parameter, "force". If it is missing or false, and "ok" is defined, check just echoes the prior result. If it is true, then check actually checks the status regardless of the "ok" flag.
new
"new" creates and returns an appropriate plot object, or dies on failure.
Each "new" method should accept the following options, defined as in the description for PDL::Graphics::Simple::new (above). There is no need to set default values as all arguments should be set to reasonable values by the superclass.
For file output, the method should autodetect file type by dot-suffix. At least ".png" and ".ps" should be supported.
Required options: "size", "type", "output", "multi".
plot
"plot" generates a plot. It should accept a standardized collection of options as generated by the PDL::Graphics::Simple plot method: standard plot options as a hash ref, followed by a list of curve blocks. It should render either a full-sized plot that fills the plot window or, if the object "multi" option was set on construction, the current subwindow. For interactive plot types it should act as an atomic plot operation, displaying the complete plot. For file plot types the atomicity is not well defined, since multiplot grids may be problematic, but the plot should be closed as soon as practical.
The plot options hash contains the plot options listed under "plot", above, plus one additional flag - "oplot" - that indicates the new data is to be overplotted on top of whatever is already present in the plotting window. All options are present in the hash. The "title", "xlabel", "ylabel", and "legend" options default to undef, which indicates the corresponding plot feature should not be rendered. The "oplot", "xrange", "yrange", "crange", "wedge", and "justify" parameters are always both present and defined.
If the "oplot" plot option is set, then the plot should be overlain on a previous plot, not losing any range settings, nor obeying any given. NOTE that if any data given to the original plot or any overplots might be changed before plot updates happen, it is the user's responsibility to pass in copies, since some engines (Prima and Gnuplot) only store data by reference for performance reasons. Otherwise the module should display a fresh plot.
Each curve block consists of an ARRAY ref with a hash in the 0 element and all required data in the following elements, one PDL per (ordinate/abscissa). For 1-D plot types (like points and lines) the PDLs must be 1D. For image plot types the lone PDL must be 2D (monochrome) or 3D(RGB).
The hash in the curve block contains the curve options for that particular curve. They are all set to have reasonable default values. The values passed in are "with" and "key". If the "legend" option is undefined, then the curve should not be placed into a plot legend (if present).
Setting some environment variables affects operation of the module:
See "new".
If this is a meaningful thing for the given engine, this value will be used instead of the driver module guessing.
Overrides passed-in arguments, to create the given file as output. If it contains %d, then with Gnuplot that will be replaced with an increasing number (an amazing PDL::Graphics::Gnuplot feature).
Deal with legend generation. In particular: adding legends with multi-call protocols is awkward and leads to many edge cases in the internal protocol. This needs more thought.
<https://github.com/PDLPorters/PDL-Graphics-Simple>
Craig DeForest, "<craig@deforest.org>"
Copyright 2013 Craig DeForest
This program is free software; you can redistribute it and/or modify it under the terms of either: the Gnu General Public License v1 as published by the Free Software Foundation; or the Perl Artistic License included with the Perl language.
see http://dev.perl.org/licenses/ for more information.
| 2025-01-17 | perl v5.40.0 |