mpad &p = mpad::mknew(3,2).width(1,4*CM).rwidth(2,3).rwidth(3,1).draw_border(true); // divide your canvas into a 3x2 grid of pads set the first column width to 4 cm, // and the remaining horizontal space is divided among cols 2 and 3 in a ratio 3:1 p.cd(1,1); // activate the lower left one plot("datafile"); p.cd(2,2); // activate the upper right plot("anotherfile"); // this example shows how to plot different files in the different subpads // of an mpad mpad &p2 = mpad::mknew(3,3); for(var i=0; i<9; ++i, p2.cd_next()) { plot("file" & i); }
Mpad (multi-pad) is an object which can be used to set up multiple pads arranged in a grid.
An mpad can be created with the static member functionmpad &mpad::mknew(int N1,int N2);
This function creates a new mpad consisting of a N1 x N2 grid of pads, adds it into the current pad, and it returns a reference to the new object. The lower left subpad in this mpad will be activated (that will be the current pad).
A uniform gap between the columns and rows can be specified with the
mpad &mpad::gap(const length &);function.
Widths and heights of pad columns or rows can be specified in two ways:
mpad &mpad::width (int col_index, const length &width ); mpad &mpad::height(int row_index, const length &height);
mpad &mpad::rwidth (int col_index, double ratio); mpad &mpad::rheight(int row_index, double ratio)functions. If for example one calls rwidth(1,3).rwidth(2,1), then the available space will be distributed amongst columns 1 and 2 in the ratio 3:1. Initially every column and row size is set to a relative dimension of 1.
An mpad is also a container, its own coordinate system extends from the lower left corner of its lower left subpad, to the upper right corner of its upper right subpad.
The visual properties (bordercolor, borderwidth, etc) of all its subpads can be set with one single call to mpad's member functions, which have the same calling syntax as those of pad:
mpad &mpad::draw_border(bool); // switch on/off border-drawing mpad &mpad::bordercolor(const color &); // color of the border (not too surprisingly) mpad &mpad::borderwidth(const length &); // set the width of the border mpad &mpad::border_3D(bool); // draw a 3D border mpad &mpad::bgcolor(const color &); // set the bgcolor, and implicitely call fill_bg mpad &mpad::fill_bg(bool); // fill the background with bgcolorTo activate a subpad of an mpad (that is, to make it the currently active pad), you can use the
mpad &mpad::cd(int i,int j);member function. The indexes i and j run from 1 to N1 or N2, respectively, (1,1) meaning the lower left one.
There is also another cd(int) function with a single integer argument, so that one can select any subpad with a single running index. The subpads are numbered depending on the looping direction (see here below) set for the pad. If, for example, the looping direction is set to right_down, the subpads are numbered like this:
1 | 2 | 3 |
4 | 5 | 6 |
1 | 3 | 5 |
2 | 4 | 6 |
There is a mechanism to automatically loop over the subpads of an mpad in a specified direction. This is done by the cd_next() function of mpad.
The possible values for the direction of looping are defined within the mpad class:
enum {right_up, right_down, left_up, left_down, up_right, up_left, down_right, down_left, jump}and can be set by the mpad::direction(int) function for one mpad, or globally, the default value can be set via the static mpad::default_direction(int) function. The default value is right_down (as you read/write). For example:
mpad::default_direction(mpad::right_down | mpad::jump); mpad &p = mpad::mknew(3,3); // create 3x3 grid p.cd(1,3); // change to left upper subpad for(int i=0; i<9; ++i, p.cd_next()) { plot(...); }
For example the meaning of right_up is to go one subpad right (when cd_next() is called), and if the end of the line is reached, go to the leftmost pad in the above-lying line. If the last subpad is reached in this order, the behaviour of cd_next() depends on the jump flag being set or unset. If it is set (see above), then cd_next() jumps to the first subpad in the specified order, and returns true. Otherwise it does nothing, and returns false to have a feedback about reaching the end of the sequence.
A subpad of an mpad can be directly accessed by the parenthesis operator:
pad *mpad::operator() (int ix, int iy);For example, this code below creates a 4x4 mpad, and creates a shared legendbox to the lower-right one:
mpad &p = mpad::mknew(2,2).gap(4*MM); legendbox &leg = legendbox::mknew(*p(2,1)); // create the legendbox in lower-right subpad frame::current().legend(leg); plot(something); p.cd_next(); frame::current().legend(leg); plot(something_else); p.cd_next(); frame::current().legend(leg); plot(something_else);
Source files: mpad.h mpad.cc