Graph marker size legend

Snippet to make a basic legend if the size of graph markers is used to display an additional parameter in xy plots, see macro examples() below.

function MarkerSizeLegend(string grName, string trName, int nPoints, variable YminFrac, variable YmaxFrac, variable Xfrac)
 	// grName: Gaph name or "" for top window
 	// trName: Trace name (e.g. w or w#1), NOT a wave name string
 	// nPoints: number of markers for the legend
 	// YminFrac, YmaxFrac: min and max of relative vertical plot area to be used for legend
 	// Xfrac: x position of legend as relative plot area  
 		
	// get zmrk-info from trace of interest
	string trInfo = TraceInfo(grName, trName, 0)
	if(strlen(trInfo) == 0)
		print "Trace not found!"
		return 0
	endif
	
	// get marker size info
	string S_info = StringbyKey("zmrkSize(x)", trInfo, "=")
	
	// get content in-between {}
	string SizePara 
	SplitString/E="\{([^}]*)\}" s_info, SizePara

	// sizePara contains 5 elements
	string sW_Size = StringFromList(0, SizePara, ",")
	string sMinVal = StringFromList(1, SizePara, ",")
	string sMaxVal = StringFromList(2, SizePara, ",")
	string sMinMrkSize = StringFromList(3, SizePara, ",")
	string sMaxMrkSize = StringFromList(4, SizePara, ",")
	
	// get basic maker shape parameters
	string sMode = StringbyKey("mode(x)", trInfo, "=")
	string sMarker = StringbyKey("marker(x)", trInfo, "=")
	string sMrkThick = StringbyKey("mrkThick(x)", trInfo, "=")
	string sStroke = StringbyKey("useMrkStrokeRGB(x)", trInfo, "=")
	string sRgb = StringbyKey("rgb(x)", trInfo, "=")
		
	// is size wave multidimensional?
	variable isMD = stringmatch(sW_size, "*[*")
	
	if(isMD)
		string name, xRow, yCol
		// split e.g. wave0[*][2] or wave0[*][%zData] into wave name, row and column info
		splitstring/E="(.*?)\[(.*?)\]\[(.*?)\]" sW_size, name, xRow, yCol
		wave w = $name
		
		// now find column or row that contains size scaling
		// xRow can be a number or a DimLabel with preceeding %
		variable DimLabelCheck, SizeCol, SizeRow
		if(cmpstr(xRow, "*")==0)	
			DimLabelCheck = strsearch(yCol,"%",0)
			SizeCol = DimLabelCheck == -1 ? str2Num(yCol) : FindDimLabel(w, 1, yCol[1,inf])			
			MatrixOP/FREE W_Size = col(w, SizeCol)
		
		elseif(cmpstr(yCol, "*")==0)
			DimLabelCheck = strsearch(xRow,"%",0)
			SizeRow = DimLabelCheck == -1 ? str2Num(xRow) : FindDimLabel(w, 0, xRow[1,inf])		
			MatrixOP/FREE W_Size = row(w, SizeRow)
		else
			return 0
		endif
	
	else
		wave W_Size = $sW_size
	endif
	
	// what are the min/max values that markers are scaled against?
	variable MarkerMinVal, MarkerMaxVal
	if(cmpstr(sMinVal, "*")==0)
		MarkerMinVal = WaveMin(W_size)
	else
		MarkerMinVal = str2num(sMinval)
	endif
	
	if(cmpstr(sMaxVal, "*")==0)
		MarkerMaxVal = WaveMax(W_size)
	else
		MarkerMaxVal = str2num(sMaxval)
	endif
	
	// make marker legend wave with nPoints scaled to min/max values			
	Make/O/N=(nPoints, 2) M_mrkSize = 0
	SetDimlabel 1, 0, relSize, M_mrkSize
	SetDimlabel 1, 1, Pos, M_mrkSize
	Setscale/I x MarkerMinVal, MarkerMaxVal, M_mrkSize
	M_mrkSize[][%relSize] = x
	
	// append to top graph, first remove if present
	RemoveFromGraph/Z M_mrkSize
	AppendToGraph/R=R_mSize/B=B_mSize M_mrkSize[][%relSize] vs M_mrkSize[][%Pos]
	
	// set new right axis 
	ModifyGraph axisEnab(R_mSize)= {YminFrac,YmaxFrac}
	ModifyGraph freePos(R_mSize)={1-xFrac,kwFraction}
	ModifyGraph tick(R_mSize)=2,btLen(R_mSize)=3
	SetAxis/A/N=1 R_mSize
	
	// set new bottom axis		
	ModifyGraph axisEnab(B_mSize)={xFrac-0.1,xFrac}
	ModifyGraph freePos(B_mSize)={yMinFrac,kwFraction}
	ModifyGraph noLabel(B_mSize)=2, tick(B_mSize)=3, axThick(B_mSize)=0
	
	// apply marker parameters
	string mrkPara
	sprintf mrkPara, "ModifyGraph mode(M_mrkSize)=%s,marker(M_mrkSize)=%s,mrkThick(M_mrkSize)=%s,useMrkStrokeRGB(M_mrkSize)=%s, rgb(M_mrkSize)=%s", sMode, sMarker, sMrkThick, sStroke, sRgb
	Execute/Z mrkPara
	
	// then update size parameters
	string zmrkStr
	sprintf zmrkStr, "ModifyGraph zmrkSize(M_mrkSize)={M_mrkSize[*][0], %s, %s, %s, %s}", sMinVal, sMaxVal, sMinMrkSize, sMaxMrkSize 
	Execute/Z zmrkStr
end


macro examples()
	Make/O/N=40 xx=p+enoise(0.1*p), yy=p+enoise(0.1*p), zz= 10*gauss(p, 20, 10) 
	
	// 1: set of 1d waves
	Display yy vs xx
	ModifyGraph mode=3,marker=19,useMrkStrokeRGB=1
	ModifyGraph zmrkSize(yy)={zz,*,*,2,10}
	MarkerSizeLegend("", "yy", 5, 0.1, 0.5, 0.9)
	
	// 2: single 2d wave with dimlabels
	Concatenate/O/DL {xx,yy,zz}, data
	Display data[][%yy] vs data[][%xx]
	ModifyGraph mode=3,marker=19,useMrkStrokeRGB=1
	ModifyGraph zmrkSize(data)={data[*][%zz],*,*,2,10}
	MarkerSizeLegend("", "data", 5, 0.5, 0.9, 0.15)
endMacro

 

Forum

Support

Gallery

Igor Pro 10

Learn More

Igor XOP Toolkit

Learn More

Igor NIDAQ Tools MX

Learn More