Prev: frame.html Up Next: graph.html
Multi-frame

Practical Guide:
mframe &f = mframe::mknew(2,2);     // create a multiframe with 2x2 subframes
f.cd(1,1);                          // change to the lower left
plot("datafile");                   // ... and plot something in it
f.cd(1,2);                          // change to the lower right
....

Mframe (multi-frame) is an object which can be used to set up multiple frames arranged in a grid. The frames within one column share their horizontal axes (x1 and x2), and the frames within one row share they vertical axes (y1 and y2). This means, that for example the x1-range of the frames within one column is the same, and the x1 axis is drawn only for the lowest frame, and other frames above it will only display the tics of this axis.

Creating an mframe
An mframe can be created with the static member function
mframe &mframe::mknew(int N1,int N2);
This function creates a new mframe (within the current pad), consisting of a N1 x N2 grid of frames, and returns a reference to the newly created object. The convention for indexing the frames is the following: horizontal indices run from 1 to N1, vertical indices run from 1 to N2, and (1,1) refers to the lower left frame, (N1,N2) refers to the upper right frame.

Making a subframe the current (active) frame:
To make the subframe (i,j) be the currently active frame, use the member funtion
mframe &mframe::cd(int i,int j);

By default, when an mframe is created by the mknew function (see above), the active frame is automatically set to be the first subframe in the looping direction (see below). Since the default looping direction is right_down, the first subframe is the left-top one. However, if an mframe is not created by mknew, the constructor of mframe does not change the active frame.

There is also another cd(int) function with a single integer argument, so that one can select any subframe with a single running index. The subframes are numbered depending on the looping direction (see here below) set for the frame. If, for example, the looping direction is set to right_down, the subframes are numbered like this:

123
456
If the direction is down_right, the subframes are numbered like this:
135
246
etc....

Looping over the subframes
One very often wants to plot several datafiles/functions in subsequent subframes of an mframe, and in this case it is difficult to keep track of the horizontal and vertical indices within the mframe. This is the point where the genious cd_next() function helps: it loops over the subframes in a user-specifiable direction. The direction can be set via the direction(int) member function (there is also a default_direction(int), see the design concepts). The arguments can be mframe::right_down, mframe::right_up, mframe::down_right, etc. The default direction is right_down. If the mframe::jump is ORed with these values, the looping jumps to the beginning when it reaches the last subframe in the given direction, and cd_next() will always return true. Otherwise, if cd_next has reached already the last subframe in the given direction, it will do nothing and return false.
mframe &f = mframe::mknew(3,3).direction(mframe::right_up);
for(var i=0; i<9; ++i, f.cd_next())
{
  plot("datafile" & i);
}

Direct access to a subframe
A subframe can be directly accessed by the parenthesis operator (with 2 indices), which returns a pointer to the given subframe:
frame *mframe::get(int i,int j); 

An mframe is also a container, its own coordinate system extends from the lower left corner of its lower left subframe to the upper right corner of its upper right subframe.

Setting the sizes of rows/columns
The sizes of the subframes, and the gap between the subframes can be set in an analogous way to mpad (see there).

Setting gap size between subframes
Use the mframe::gap(const length &) member function to make a gap between the subframes (so that they do not touch each other).

The frame margins
For a single frame, a margin is called the area reserved for the axis tics and axis titles. In the case of the mframe, this is automatically calculated from the corresponding values of all subframes (for example the left margin being the maximum to hold all y1 axes' tics and titles). These dimensions can be obtained by
length &mframe::lmargin();
length &mframe::rmargin();
length &mframe::bmargin();
length &mframe::tmargin();

The margins can be also overwritten by calling the above functions with a length argument. In this case the corresponding margin is forced to be the given length, and will not be calculated to nicely accumulate all axis tics/titles:

mframe &mframe::lmargin(const length &);
// etc....

Hiding a subframe
By default, all subframes of an mframe are shown. If you want to hide some of them, use this member function:
mframe &mframe::show_subframe(int i, int j, bool show);

Setting the title for a mframe

Use the member function mframe::title(const var &) to set the title, which will be positioned at the top margin of the mframe, centered horizontally.

mframe &mf = mframe::mknew(2,2).title("This is the title").gap(2*MM);

Source files:
   mframe.h
   mframe.cc

Prev: frame.html Up Next: graph.html