Cursor commands





The cursor pseudo object, the most complex pseudo object supported by plt, consists of one or more markers and several uicontrols with complex interactions. Because of this you normally will not create cursor objects on your own, but will rely on plt to create them automatically when you specify the data to be plotted. However it is possible to create a cursor object manually with the cursor init command described at the end of this section. For many casual plotting applications, the plt cursors will behave as desired out of the box. For more sophisticated applications you may want to modify the cursoring behavior using the plt parameters (DualCur, Xstring, Ystring, Options) or the independent cursor commands shown below.

DualCur parameter:

Normally the cursor value for only a single trace (referred to as the active trace) is shown in an edit box below the plot. However sometimes it is convenient to show the y-value for two traces simultaneously. This is done by using the 'DualCur' parameter which specifies a trace which will always have a display of its y-value on the screen in addition to the display of the active trace. Try out the editz.m demo program which uses Dual Cursors to simultaneously display the magnitude and phase of a transfer function. (In fact, transfer function displays were the problem that inspired the Dual Cursor feature.) The alternate method of specifying the dual cursor trace (as an offset from the active trace) is indicated by using a negative number for the DualCur parameter. The demo program gui2.m demonstrates the use of that mode. The use of the DualCur mode is covered in more detail near the end of the cursoring guide found here: Cursoring.

Xstring and Ystring parameters:

The 'Xstring' and 'Ystring' plt arguments allow you to add text strings just to the right of the cursor X or Y readout values. Since these strings occupy the same screen area as the delta cursor readouts, they get covered up when you are in delta cursor mode (or a if a zoom window is visible). However those are usually temporary modes, so as you will see, these strings still prove useful.
String Replacement value
@CID cursor ID
@XVAL active cursor X position
@YVAL active cursor Y position
@XY same as complex(@XVAL,@YVAL)
@IDX active cursor index
@HAND handle of active trace
@LNUM  line number of active trace
@XU Xstring user value
@YU Ystring user value

Most of the power of the Xstring and Ystring parameters stem from their string replacement feature described in this table. Strings in the first column of the table are replaced with the value shown in the second column. (The Xstring and Ystring are both updated every time the cursor is moved.)

Xstring/Ystring Examples:

Suppose it was important to see the cursor index as well as the usual cursor x and y values (i.e. you want to know that your are looking at the sixty fifth data element for instance). You could do this as follows:

plt(x,y,'xstring','sprintf("index = %d",@IDX)');

A string within a string (such as the 'index = %d' above) is normally written in Matlab using two consecutive single quote characters on both sides of the string. Since this can get verbose and confusing at times, callbacks defined within plt may use a double quote character instead of two successive single quotes. That's why the double quotes appear in the line above.

Although the mean of the active trace y values can be shown using one of the usual cursor features, suppose you wanted to display the mean of the entire data set (independent of the viewing window). Suppose also that you want to continuously display the y/x ratio. (This ratio is also a standard cursor feature, but its not continuously visible.) You could accomplish both of those feats as follows:

plt(x,y,'xstring','sprintf("mean: %f",mean(get(@HAND,"y")))',...
        'ystring','prin("Y/X: %5w",@YVAL/@XVAL)');


Suppose your x axis is measured in seconds with a zero reference of 5pm, 21-Jan-2007 UTC. The cursor x-axis readout will be in seconds past the reference, but you may want an additional cursor readout that shows the actual time of day. This can be accomplished as follows:

plt(t,y,'xstring',...
  'sprintf("utc:%s",datestr(datenum("21-Jan-07 17:00")+@XVAL/86400,13))');


Note the 86400 (the number of seconds in a day) is needed because date numbers are measured in days. If your x axis unit was "weeks", you would replace /86400 with *7.  If you removed the ,13 near the end of the line (date string format), then the readout would show the complete date and time instead of just the time. Another way to code the statement above is:

plt(t,y,'xstring','sprintf("utc: %s",datestr(@XU+@XVAL/86400,13))');
set(findobj(gcf,'tag','xstr'),'User',datenum(2007,1,21,17,0,0));


The second statement puts the reference time in the Xstring user value which is used by plt when updating the Xstring. This method is much more convenient when the reference time can change. Note that the reference time is identical to that used above, although it's written in the vector format instead of the character format.

Sometimes the 1 second resolution provided by datestr is not sufficient. You can increase this resolution to 1 millisecond by using the date string function provided by plt as follows:

plt(t,y,'xstring','sprintf("utc: %s",plt("datestr",@XU+@XVAL/86400,13))');

Occasionally its useful to use an edit box instead of a string for one or both of these customized cursor controls. (The pltn.m example does this for the Xstring, although the Ystring is still rendered as a text string.) To do that, simply insert a question mark before the string. The first example above is rewritten below to use an edit box.

plt(x,y,'xstring','?sprintf("index = %d",@IDX)');

Cursor commands

Notes: The cid (cursor ID) that appears in all the commands shown below is an integer that identifies the cursor the command is to act on. This integer is returned from the cursor initialization command used to create the cursor. If an axis contains a cursor, its cid is saved in the axis user data. (The cid stored in the axis user data is always a scalar since an axis may only contain a single cursor object.) You can specify that the cid should be retrieved from the axis user data by specifying a zero for the cid. So for example the following two commands have the same effect:

plt('cursor',0,'set','visON')
plt('cursor',get(gca,'user'),'set','visON')
  The figure 'cid' application data variable contains a vector with the cursor IDs for all the cursor objects in the figure. You can specify that the cid should be retrieved from this vector by supplying a negative number as the cid (for example -2 specifies the 2nd element of this vector). This means that the following two lines have the same effect:

xy=plt('cursor',-2,'get');
c=getappdata(gcf,'cid'); xy=plt('cursor',c(2),'get');
  All the following commands are case sensitive (unlike all the other plt parameters previously described) and must use the exact case shown below.
  All the cursor commands below may return up to two arguments. If the return arguments are listed for a cursor command, the return values will be as specified. However if the return arguments are not listed for a particular command, the first return value (if requested) will be the active cursor handle and the second return value (if requested) will be the active line handle.

[xy k] = plt('cursor',cid,'get',n);
Get x and y coordinates of the cursor location the last time it was on trace #n. The trace number is optional - if it is not specified then the position of the active trace is returned. xy is a complex value. Its real part is the cursor x-coordinate and its imaginary part is the y coordinate. The second return value (if requested) is the index into the x data vector of the cursor position.

[n h] = plt('cursor',cid,'getActive');
Returns the line number of the active cursor. The second return value (if requested) is the handle of the active trace.

h = plt('cursor',cid,'obj');
Returns an 13 element vector of handles to the following cursor objects:
    1:  x label     5:  y cursor readout     09:  marker line-style button     13:  cursor marker
    2:  y label     6:  y cursor expansion     10:  delta button
    3:  x cursor readout     7:  peak button     11:  expansion box
    4:  x cursor expansion     8:  valley button     12:  delta cursor  

u = plt('cursor',cid,'expHis');

Returns an array containing the display expansion history.
Each row contains one display expansion as [xmin, xmax, ymin, ymax, code] where:

plt('cursor',cid,'visON');
plt('cursor',cid,'visOFF');

Shows or hides the following objects:

Note that this function is invoked alternately (visOFF/visON) when you right-click on the plot y-axis label (which also hides/shows the menu box).

plt('cursor',cid,'aux','on');
plt('cursor',cid,'aux','off');

Shows or hides the auxiliary (dual) cursor and its edit box

plt('cursor',cid,'setObjPos',p);
Sets the cursor object positions to p, where p is a 9 by 4 element array. Each row contains (x,y,width,height) which represents the position and size of the following objects:

  1. x-axis edit box label
  2. y-axis edit box label
  3. x-axis edit box (cursor readout)
  4. x-axis cursor expansion edit box
  5. y-axis edit box (cursor readout)
  6. y-axis cursor expansion edit box
  7. peak button
  8. valley button
  9. delta cursor button

Note that this command does not set the position of the optional x-axis control slider. However you can set this position using the plt 'xy' parameter, or with a command such as:
set(findobj(gcf,'tag','xslider'),'position',p);

plt('cursor',cid,'xlim',p);
Set new x axis limits and update expansion history, where p=[xmin,xmax]

plt('cursor',cid,'ylim',p,pAux);
Set new y axis limits and update expansion history, where p=[ymin,ymax].
and optionally pAux=[ymin,ymax] (for the right hand axis).

plt('cursor',cid,'xylim',p,pAux);
Set new x and y axis limits and update expansion history, where p=[xmin,xmax,ymin,ymax].
and optionally pAux=[ymin,ymax] (for the right hand axis).

plt('cursor',cid,'exRestore',u);
Restores an expansion history previously saved in u.

plt('cursor',cid,'axisCB',fcn);
String fcn will be evaluated whenever an axis limit is changed. This cursor command overwrites any axis callback function entered using the 'axisCB' parameter on the plt command line. The rules for string substitutions and function handles are the same as mentioned below in the moveCB command.

plt('cursor',cid,'moveCB',fcn);
String fcn will be evaluated whenever the cursor is moved. Before the fcn string is evaluated all occurrences of  the strings in the 1st column of the table above ( @CID, @XVAL, @YVAL, @XY, @IDX, @HAND, @LNUM, @XU, @YU) are replaced with the values in the 2nd column of that table. fcn is not called by events initiated from outside the figure window containing the cursor. (For example a button push that moves the cursor in another figure window would not activate the callback. This prevents infinite loops when figure A modifies figure B's cursor and visa versa.) If you do want to enable the callback for external events, insert an extra semicolon as the first character of the moveCB callback string. This cursor command overwrites any axis callback function entered using the 'moveCB' parameters on the plt command line. In addition to a string, fcn may also be a function handle of the form @func or {@func,arg1,arg2,...,argn}. Note that the string substitutions can't be used with the function handle form of this parameter. Also note that a similar callback is provided for the TraceID fields, although the string substitutions allowed are different than the ones mentioned above. See the 'TIDcback' parameter under Trace properties.

plt('cursor',cid,'moveCB2',fcn);
This call operates similarly to the set moveCB command shown above and the functions specified in both these calls are executed whenever the cursor is moved. However normally you will not want to use this call because the moveCB2 function is used internally by plt to keep the CursorID tag (just to the left of the y-axis cursor readout) so that it always identifies the cursored trace name. It's also used by plt in the linked subplot mode to keep the plots in a column synchronized. In rare situations you may wish to modify those behaviors, which you can do with the moveCB2 function.

plt('cursor',cid,'setActive',a,k);
Switches the active cursor to the line specified by  a (a must be an integer between 1 and the number of lines in the plot). The cursor will be placed at index k. If k (optional) is out of bounds or not supplied, then the cursor will be placed in the center of the array. When a is zero (a special case), the active line remains the same and only the cursor index is changed - which would have the the same as calling the update command (below).

plt('cursor',cid,'update',k);
plt('cursor',cid,'updateH',k);
plt('cursor',cid,'updateN',k);

Moves the active cursor to index k in the data set and calls any user defined cursor callbacks (moveCB, xstring, ystring). If k is out of bounds, the cursor is set to the middle of the array associated with the active trace. If you do not supply the argument k, then the command does not move the cursor, however it does execute the cursor callbacks. If update moves the cursor to an area that is not inside the current axis limits, it will shift the axis limits to make the cursored data element visible. However when the cursor is moved by updateH the axis limits will never be adjusted. (Think of this as "Update, Hold".) Also updating the cursor with the updateN command has the same effect as using the updateH command except that the cursor callback function (defined by 'MoveCB') is not called like it is with the update and updateH commands.

When the index is not needed we can abbreviate the update command by omitting the 'update' string. This means that the following two lines are equivalent:
    plt('cursor',cid);
    plt('cursor',cid,'update');

We can abbreviate the update command even more by omitting the cursor ID which defaults to -1. This means that the following two lines are equivalent:
    plt('cursor');
    plt('cursor',-1);

And finally there is one more variant of the update and updateH commands:
    plt('cursor',cid,'update',k,x,y);
    plt('cursor',cid,'updateH',k,x,y);

The moves the active cursor to the index k as above. Normally x and y would be the position of the kth element of the array associated with the active trace, in which case this command behaves the same as if you didn't include the last two parameters. However x and y can be any position on the axis, and the visible cursor marker will be moved to those coordinates. (It's rare to want to move the cursor off the line, but it may sometimes be useful.)

plt('cursor',cid,'peakval',0);
plt('cursor',cid,'peakval',1);

Moves the active cursor to the next peak (0) or to the next valley (1)

plt('cursor',cid,'clear');
All the cursor objects are deleted.

plt hideCur;
Has the same effect as right-clicking on the y-axis label. See cursoring. If you also want to hide the TraceID box, use the commands:
tbox=findobj('user','TraceID'); set([tbox; get(tbox,'child')],'vis','off').

Note: The following cursor commands were designed primarily for plt internal use, although sometimes they may also be useful in your programs. (These commands are case sensitive.) The "0" in the first seven commands below refers to the current cursor. You may replace the "0" with the actual cursor ID number, or "-n" to refer to the nth cursor.

plt cleft 0 ZoomOut; Zoom out both x & y axis by 40%.
plt cright 0 ZoomOut;  
Zoom in both x & y axis by 40%. With the functional form (which applies to the command above as well), you may also include an additional argument which specifies the zoom ratio. For example, this command specifies a 20% ratio (half of the default amount): plt('cright',0,'ZoomOut',.2);

plt cleft 0 peakval 0; Move the cursor to the next peak. (The last argument may be omitted in this case.)
plt cleft 0 peakval 1; Move the cursor to the next valley
plt cleft 0 peakval 2; Reset the peak finder (i.e. move the cursor to the highest peak)
plt cleft 0 peakval 3; Reset the valley finder (i.e. move the cursor to the lowest valley)
plt cleft 0 TGLlogy; Toggle the y-axis between linear/log
plt cleft 0 TGLlogx; Toggle the x-axis between linear/log
plt cright 0 TGLlogy; Open Hardcopy menu
plt cright 0 TGLlogx; Swap x & y axes
plt cleft 0 markCB; Toggle the delta cursor mode on or off
plt cleft 0 mlsCB; 3 way toggle of all traces between markers only, lines only, and both lines & markers
plt cleft 0 mark; Adds a text label identifying the current cursor location
plt xleft TGLgrid; Toggle between grid lines and ticks
plt xright TGLgrid; Toggle between default and alternate grid style
plt xleft TGLmenu; Toggle the menu bar on/off
plt xright TGLmenu; Open a cursor data window
plt xleft mark 2; Open a window allowing editing plt figure colors
plt xleft mark 3; Write a file saving the current plt figure colors
plt xleft link; Toggle right hand axis link status
plt xleft RMS;
Equivalent to clicking on the cursorID tag which rotates between the five cursor modes [normal, Avg, RMS, y/x, sqrt(x^2+y^2)]. After five of these commands the cursor mode will be the same as it was before the first of those commands (having rotated thru all the modes).

plt xleft EDIT 1; Enter data editing (using last used editing mode)
plt xleft EDIT 2; Open up Yedit popup menu
plt xleft EDIT 5; Exit data editing mode
plt xleft Yedit 1; Open a window allowing editing the line properties of cursored trace. (The command plt xright mark;) also does the same thing.
plt xright Yedit 1; Open a window allowing editing the plt figure properties
plt xleft Yedit 2; Toggle multiCursor mode
plt xleft Yedit 3; Toggle xView slider
plt xleft Yedit 4; Cancel data editing mode
plt xleft Yedit 5; Enter data edit mode (Range)
plt xleft Yedit 6; Enter data edit mode (Range left/right)
plt xleft Yedit 7; Enter data edit mode (Range up/down)
plt xleft Yedit 8; Enter data edit mode (Modify)
plt xleft Yedit 9; Enter data edit mode (Modify left/right)
plt xleft Yedit 10; Enter data edit mode (Modify up/down)
plt xright Yedit 8; Enter persistent data edit mode (Modify)
plt xright Yedit 9; Enter persistent data edit mode (Modify left/right)
plt xright Yedit 10; Enter persistent data edit mode (Modify up/down)

Mouse motion functions:

If you create a figure with a plt command that includes the parameter 'MotionZoom','funcname', then if you create a zoom box (see The expansion box) while you are adjusting the size of the zoom box the function funcname([x1 x2 y1 y2]) will be continually called as the mouse is moved (i.e.  for as long as the mouse button is held down). The coordinate [x1 y1] is the position of the lower left corner of the zoom box and [x2 y2] is the coordinate of the upper right corner. It may require some imagination to see how using such a parameter would enhance your user interface. The example demo\gauss.m shows how to use the 'MotionZoom' function. Although the use of the MotionZoom feature in this program is not inspirational, at least when you create a zoom box inside the gauss figure you will see the effect that the MotionZoom parameter creates. A more practical demonstration of the use of this parameter can be seen in the pltmap.m example.

In place of the character string 'funcname' you may also use @funcname or to insert extra parameters to the function, use {@funcname param1 param2}. (The 4 element vector specifying the zoombox corners will be the 3rd parameter of the function in this example.) These alternate forms also apply to the other mouse motion functions

Including the parameter 'MotionZup','funcname' has a similar effect except that the function 'funcname' only is called when the mouse button is released. The MotionZoom and MotionZup functions are called when the zoom box moved or resized as well as when it is first created.

You may also create, modify, or remove these mouse motion functions after the call to plt by modifying the corresponding application data variable associated an axis. For example these commands will set the mouse motion functions as expected:
    setappdata(gca,'MotionZoom','funcA');
    setappdata(gca,'MotionZup',@funcB);

Three additional mouse motion functions (MotionEdit, EditStart, EditStop) may also be defined and are described in the Data Editing section.

Creating a cursor pseudo object:

Usually the cursor objects are initialized from the main plt() call that specifies the data arrays to be plotted. However you may also create the cursor objects using this cursor 'init' call after creating a figure on your own (i.e. without using the plt pseudo object).

Ret1 = plt('cursor',axis,'init',In1,In2,In3,In4,In5,In6,In7,In8,In9);

where:

Notes:

When the plt('cursor','init' function is called, plt will attempt to add cursors to all lines of the axis created by plt. If you want plt to skip adding cursors to some of the lines, you should tag the line with the string 'SkipCur'. For example, a cursor would not be created for a line created with the following command: line(x,y,'tag','SkipCur');
  Another way to restrict which lines are to be cursored is to add the application data key 'Lhandles' to the axis. (For example: setappdata(ax,'Lhandles',[h1 h3]); would tell the cursor initialization routine to add cursors only to those two handles.)