Automatically label axes according to the plotted waves or trace names

Run autoLabelAxes(symbol=2) to label all axes by their trace names.

#pragma TextEncoding = "UTF-8"
#pragma rtGlobals=3             // Use modern global access method and strict wave access
#pragma DefaultTab={3,20,4}     // Set default tab width in Igor Pro 9 and later
 
 
// Label all axes according to the plotted trace, iff one trace is plotted.
function autoLabelAxes([symbol])
// If two traces are plotted, no change is made to the label.
// variable symbol : Adds the legend symbol of the trace as well.
//
// Bar charts and fancy colours are not supported.
// Adapted from autoColourAxes() by jcc on 170724.
//
//  autoLabelAxes()  // axes labelled with "\c" (wave name)
//  autoLabelAxes(symbol=1)  // axes labelled with "symbol and trace name" (like Legend)
//  autoLabelAxes(symbol=2)  // axes labelled with "trace name" (like Legend but no symbol)
//
variable symbol
 
// 1. Use tracerepeat() to get trace list
    string visibleTraces= TraceNameList("", ";", 2^0 + 2^1 + 2^2)
    string topwin= winList("*","","WIN:")
    variable i, n_traces= itemsInList(visibleTraces)
    variable n_axes= itemsinList(AxisList(topwin))
    string cmd
    string nxLabel
    string pastAxes= ""
    string unchangedList= ""
    
    if (n_traces==1)
        // don't bother with symbols when one trace
        symbol=0
    elseif (paramIsDefault(symbol) && (n_axes-1)<3)
        // just a couple axes, do it
        symbol=1
    elseif (paramIsDefault(symbol) && strlen(getSmartSortedAxisList(type="right", win=topwin)) && strlen(getSmartSortedAxisList(type="left", win=topwin)))
        // opposite sided axes, do it
        symbol=1
    endif
    
    // somehow this command is orphaned....
    if (GrepString(AxisList(topwin), "bottom"))
        Label bottom, "\\c"
    else
        print ""
    endif
        // uando    print "bottom/top axes not handled properly by autolabelaxes() 180420....also slash TN tracenames"
    
    for (i=0; i<n_traces; i+=1)
    // 2. use TraceInfo to get trace axes  & trace colour (via TraceInfo)
        string nxTrace= stringFromList(i, visibleTraces)
        string nxtInfo= TraceInfo(topwin, nxTrace, 0)            // also works, but less controlled: TraceInfo("", "", 1)
        nxtInfo= replaceString("RECREATION:", nxtInfo, "")       // list goes: RECREATION:zColor(x)=[..];zColorMin(x)=[..];[..] so this allows 1st item retrieval
        string nxtAxis, nxtAxisFlag= StringByKey("AXISFLAGS", nxtInfo)
        strswitch (nxtAxisFlag)
            case "": // means "/L":
                nxtAxis= "left"
                break
            case "/R":
                nxtAxis= "right"
                break
            default:
                nxtAxis= stringFromList(1, nxtAxisFlag,"/")[2,inf] // ->  custom, like " /L=customAxis"...omit the /L= and the following /B= stringFromList(1, nxtAxisFlag,"/")
        endswitch
        string currLabel= AxisLabelText(topwin, nxtAxis)
        
        // check if axis was already treated
        variable alreadyTreated= strlen(grepList(pastAxes, nxtAxis))
        if (alreadyTreated && !symbol)
        elseif (alreadyTreated && symbol)
            if (symbol)
                // update existing label
                if (symbol==2)
                    nxLabel= "\\JL\\r" + currLabel + nxTrace
                else
                    nxLabel= "\\JL\\r" + currLabel + "\\r\s("+nxTrace+") " + nxTrace
                endif
            else
                // revert to previous label             
                currLabel= grepList(unchangedList, nxtAxis)     // REDUNDANT?? never used...
                nxLabel= currLabel
            endif
        else
            // build new label
            if (symbol)
                
                if (symbol==2)
                    nxLabel= nxTrace
                else
                    nxLabel= "\s("+nxTrace+") " + nxTrace
                endif
                
            else
                nxLabel= "\\c"
            endif
            pastAxes+= nxtAxis
            unchangedList+= currLabel
        endif
        
        // check if wave symbols were already coloured (zcolor)
        string thisZcol= StringByKey("zcolor(x)", nxtInfo, "=", ";") 
        variable zColourOn= cmpstr(thisZcol,"0")!=0
        if (zColourOn && symbol && 0 && 0 && 0)
            // TODO/future feature.... change marker/line to black, so symbols aren't confusing
        endif
        
        
    // 3. apply trace colour to trace axis
        sprintf cmd, "Label %s \"%s\"", nxtAxis, nxLabel
        execute cmd
    endfor
    
// 4. if axis has been coloured before, make black (if really want to waste time programming, add a coloured box to trace label for each colour (Signal [RED] [BLUE])
    return 1
end
 
// Get a sorted list of left//right//bottom//top axes. Internal function.
function /s getSmartSortedAxisList([type, win, defaultAxFirst])
string type     // "left", "right", "bottom", or "top" (== AXTYPE from AxisInfo())
string win
variable defaultAxFirst// put axis named "left" at top of list of left axes, etc
 
if (ParamIsDefault(win))
    win= "" 
else
    // check existence of window
    GetWindow /Z $win wtitle
    if (V_flag != 0)
        return "" // no window found
    endif
endif
 
// get and prune axis list
    string allAxes = AxisList(win)
    string axes = ""
    
// return axes of this type only
    variable i,n=itemsInList(allAxes)
    for (i=0; i<n; i+=1)
        string thisAxis= stringFromList(i,allAxes)
        string thisAxType= StringByKey("AXTYPE", AxisInfo(win, thisAxis))
        if (stringmatch(thisAxType, type))
            // put default axis first 
            if (stringmatch(thisAxis, type))
                axes = thisAxis + ";" + axes
            else
                axes += thisAxis + ";"
            endif
        endif
    endfor
    
// were any axes found?
    if (!strlen(axes))
        return ""
    endif
    
// sort axes according to their current order, if one exists (no special treatment of 'left')
    n=itemsInList(axes)
    variable enab0, enab1
    string ax, axEnabStr
    make /free /n=(n) enab0w, enab1w, d_enab
    make /free /T /n=(n) axNames
    for (i=0; i<n; i+=1)
        // get all ranges
        ax= stringFromList(i,axes)
        axEnabStr= stringByKey("axisEnab(x)", AxisInfo(win, ax), "=", ";")
        sscanf axEnabStr, "{%g,%g}", enab0, enab1
        
        axNames[i]= ax
        enab0w[i]= enab0
        enab1w[i]= enab1
    endfor
    Sort enab0w, axNames, enab1w, enab0w // sort by start positions
    d_enab= enab1w[p] - enab0w[p]       // check if overlap 1/2
    if (waveMin(d_enab) >= 0)           // check if overlap 2/2
        // no overlap: sort axes
        axes= textwave2list(axNames)
    else
        // either something weird, or no sort exists yet
    endif
    
    return axes
end
 
 
// GRABBED FROM #include <Axis Utilities> VIA http://www.igorexchange.com/node/603
// Returns the text of the axis label.
// If optional parameter SuppressEscaping is non-zero, extra backslashes ("\\" is required 
// to include a single backslash in a quoted string) are removed
// so that the result is a string suitable to be passed directly to the Label operation. 
STATIC Function/S AxisLabelText(graphName, axisName, [SuppressEscaping])
    String graphName, axisName
    Variable SuppressEscaping
 
    if (ParamIsDefault(SuppressEscaping))
        SuppressEscaping = 0
    endif
 
    String axisLabel=""
    String info= WinRecreation(graphName,0)
    Variable start= strsearch(info, "Label "+axisName, 0)
    if( start >= 0 )
        start = strsearch(info, "\"", start)+1
        Variable theEnd= strsearch(info, "\"", start)-1
        axisLabel= info[start,theEnd]
    endif
    if (SuppressEscaping)
        start = 0
        do
            start = strsearch(axisLabel, "\\\\", start) // search for double backslash
            if (start >= 0)
                string newLabel = axisLabel[0,start-1]
                newLabel += axisLabel[start+1, strlen(axisLabel)-1]
                axisLabel = newLabel
            else
                break
            endif
        while(1)
    endif
    return axisLabel
End
 
// Given a text wave reference, returns a string-list formatted version of the wave.
function/s textwave2list(w[, sep])
// printed using %s.
//      e.g. make /T w={"a","b","c"}; print textwave2list(w) returns "a;b;c"
    wave /T w
    string sep      // optionally specify list delimiter
    
    if (ParamIsDefault(sep))
        sep=";"
    endif
    if (!WaveExists(w) || numpnts(w)==0)
        return ""
    endif
    
    string str
    wfprintf str, "%s;", w
    
    return str
end

 

Forum

Support

Gallery

Igor Pro 9

Learn More

Igor XOP Toolkit

Learn More

Igor NIDAQ Tools MX

Learn More