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 10

Learn More

Igor XOP Toolkit

Learn More

Igor NIDAQ Tools MX

Learn More