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.
An mframe can be created with the static member functionmframe &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. 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:
1 | 2 | 3 |
4 | 5 | 6 |
1 | 3 | 5 |
2 | 4 | 6 |
mframe &f = mframe::mknew(3,3).direction(mframe::right_up); for(var i=0; i<9; ++i, f.cd_next()) { plot("datafile" & i); }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.
The sizes of the subframes, and the gap between the subframes can be set in an analogous way to mpad (see there). Use the mframe::gap(const length &) member function to make a gap between the subframes (so that they do not touch each other). 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 bylength &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....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);
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