# 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

// 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
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