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 9

Learn More

Igor XOP Toolkit

Learn More

Igor NIDAQ Tools MX

Learn More