Pie Chart Graph Markers

Snippet to make simple pie-chart graph markers on an XY plot. Drawing is based on WM's PieChart package.

Data preparation:

- Requires x and y data as 1D waves.

- Pie content is a 2D fraction/percentage wave with n columns, and the same number of rows as x and y data waves. The n values along a row are scaled, and, if non-zero, drawn as pie segments.

- Colors need to be supplied by a predefined 2D RGB color wave with n rows.

Assumptions: 

- x and y data are plotted along standard "bottom" and "left" axes, drawn from 0-100% 

- Both axes are in standard orientation, i.e. values increase away from the origin

- Probably others that have not been tested explicitly

 

Note that changing data, the graphs aspect ratio or axes ranges requires re-execution of the snippet.

Usage:

// make dummy data
Make/O xx = {1,3,6,8}
Make/O yy = {-2,5,7,9}
Make/O zz = {{75,50,20,5},{25,35,50,50},{0,15,15,15},{0,0,15,30}}
Make/O W_color = {{49151,26205,65535,16885},{53155,52428,43690,16388},{65535,1,0,65535}}

// call snippet
PlotPieMarkers(yy, xx, zz, W_color, 0.04, "PieSymbols")


 

// some constants to tweak appearance
static constant kPieLineThickness = 0.8 // wedge line thickness
static constant kMaxFrac = 1 // 1 for full circle
static constant kcClockWise = 1  // wedge order direction
static constant kAngle0 = 0 // start angle 
static constant kSmoothFactor = 100	// Polygon roundness factor
static strconstant kLayer = "ProgFront"	// active layer for pies

function PlotPieMarkers(wave yy, wave xx, wave PieContentWave, wave colorWave, variable radius, string graphName)
	// create graph if it doesn't exist
	DoWindow/F $Graphname
	if(!V_flag)
		Display/N=$Graphname yy vs xx
		Setaxis/A/N=2
		ModifyGraph mode=2,rgb=(65535,65535,65535)
	endif
	
	// clear pie layer
	SetDrawLayer/W=$GraphName/K $klayer
	
	// scale xx and yy data to "plot relative" drawing coordinates
	// avoids trouble with axes scaling and distortion
	Duplicate/FREE yy, yyScaled
	DoUpdate 		// make sure GetAxis catches correct values
	GetAxis/Q/W=$GraphName left 
	yyScaled = 1 - (yy-V_min)/(V_max-V_min)
	
	Duplicate/FREE xx, xxScaled
	GetAxis/Q/W= $GraphName bottom 
	xxScaled = (xx-V_Min)/(V_max - V_min)
	
	// draw point by point
	variable i, nPoints = DimSize(PieContentWave, 0)
	for(i=0; i<nPoints; i++)
		MatrixOP/O/FREE PointPieData = row(PieContentWave,i)^t
		DrawPieSymbol(GraphName, xxScaled[i], yyScaled[i], radius, PointPieData, colorWave)
	endfor
	
	// revert to default layer
	SetDrawLayer/W=$GraphName UserFront
end

function DrawPieSymbol(string win, variable xOrigin, variable yOrigin, variable radius, wave dataWave, wave colorWave)
	// based on WM's PieChart.ipf and function TwoDPieChart(win, pieInfo)
	Variable total, EndFrac
	Variable StartAngle, EndAngle, NumWedges
	Variable i=0,j,n
	Variable xi, yi
	variable x0, y0
	Variable angle				
	
	// get aspect ratio, lock it and define horizontal or vertical scaling 
	variable AspectRatio, hScale=1, vScale=1
	GetWindow $win psize
	AspectRatio = (V_right - V_left)/(V_bottom-V_top)
	ModifyGraph width = {Aspect,AspectRatio}
	vScale = AspectRatio
	
	// make cumulate fraction wave, starts at 0
	Duplicate/O/FREE DataWave, FracWave
	NumWedges=numpnts(FracWave)
	FracWave[1,NumWedges-1] = FracWave[p-1] + FracWave[p]	
	total = FracWave[NumWedges-1]
	FracWave = FracWave/total*kmaxFrac	
	InsertPoints 0,1,FracWave			
	
	// group all wedges at given x,y
	SetDrawEnv/W=$win gstart

	do
		// calculate polygon coordinates
		StartAngle = 2*pi*FracWave[i]
		EndAngle = 2*pi*FracWave[i+1]
		if(kcClockWise)	// if (ccw)
			StartAngle = -StartAngle
			EndAngle= -EndAngle
		endif
		
		StartAngle += kangle0
		EndAngle += kangle0
		n= ceil(max(1,abs(EndAngle-StartAngle)*(kSmoothFactor/pi)))
				
		// first point on the outer arc
		x0= radius*cos(StartAngle)
		y0= radius*sin(StartAngle)
		
		// prepare draw environment
		SetDrawLayer/W=$win $klayer
		SetDrawEnv/W=$win xcoord = prel, ycoord = prel
		SetDrawEnv/W=$win linefgc= (0,0,0),linethick= kPieLineThickness, fillfgc= (colorWave[i][0],colorWave[i][1],colorWave[i][2])
		
		// draw polygons
		DrawPoly/W=$win/ABS xOrigin, yOrigin, hScale, vScale, {0,0,x0,y0} // first and second points
		for(j=1; j<=n; j+=1)
			angle = startAngle + j * (EndAngle-StartAngle) / n
			x0= radius*cos(angle)
			y0= radius*sin(angle)
			DrawPoly/W=$win /A {x0,y0}
		endfor
		DrawPoly/W=$win/A {0,0}
		
		// stop drawing when kMaxFrac is reached  
		i+=1	
	while(FracWave[i]< kMaxFrac)
	
	SetDrawEnv/W=$win gstop
end 

 

 

 

 

 

Forum

Support

Gallery

Igor Pro 10

Learn More

Igor XOP Toolkit

Learn More

Igor NIDAQ Tools MX

Learn More