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 9

Learn More

Igor XOP Toolkit

Learn More

Igor NIDAQ Tools MX

Learn More