copy/paste trace formatting

Does this exist somewhere? I had a quick look around and couldn't find it outside of a feature request in the wishlist forum.

#pragma ModuleName=CopyTrace
#pragma version=1.11

// if you use the marquee menu to copy trace(s) you can hold option/alt
// when clicking "paste traces" to select axes

// ------ copy/paste trace formatting ---------

menu "TracePopup", dynamic
    "Copy Trace", /Q, CopyTrace#CopyTrace(0)
    "Cut Trace", /Q, CopyTrace#CopyTrace(1)
    SelectString(cmpstr(GetScrapText()[0,5], "YWAVE:")==0, "", "Paste Trace Formatting"), /Q, CopyTrace#PasteTraceFormatting(2)
    SelectString(cmpstr(GetScrapText()[0,5], "YWAVE:")==0, "", "Paste Trace Offsets"), /Q, CopyTrace#PasteTraceFormatting(1)
end

menu "GraphPopup", dynamic
    SelectString(cmpstr(GetScrapText()[0,5], "YWAVE:")==0, "", "Paste Trace"), /Q, CopyTrace#PasteTrace(GetScrapText())
    SelectString(cmpstr(GetScrapText()[0,7], "MQtraces")==0, "", "Paste Traces"), /Q, CopyTrace#PasteTraces()
end

menu "GraphMarquee"
    "Copy Traces in Marquee", /Q, CopyTrace#CopyTraces()
    "Remove Traces in Marquee", /Q, CopyTrace#HideOrRemoveMQTraces(0)
    "Hide Traces in Marquee", /Q, CopyTrace#HideOrRemoveMQTraces(1)
    submenu "Recolour Traces in Marquee"
        "*COLORPOP*", /Q, CopyTrace#SetMQTraceColor()
    end
    "Copy Marquee Tracenames", /Q, PutScrapText CopyTrace#TracesInMarquee()
end

static function CopyTrace(int cut)
    GetLastUserMenuInfo
    wave/Z w = TraceNameToWaveRef(S_graphName, S_traceName)
    if (WaveExists(w)==0)
        return 0
    endif
    string s = "YWAVE:" + GetWavesDataFolder(w,4) + ";" + TraceInfo(S_graphName, S_traceName, 0)
    PutScrapText s
    if (cut)
        RemoveFromGraph/W=$S_graphName/Z $S_traceName
    endif
end

static function CopyTraces()
    string strTraces = TracesInMarquee()
    GetMarquee/K
    int i
    int imax = ItemsInList(strTraces)
    if (imax == 0)
        return 0
    endif
    string scrap = "MQtraces\r"
    string strTrace = ""
    for (i=0;i<imax;i++)
        strTrace = StringFromList(i, strTraces)
        wave/Z w = TraceNameToWaveRef(S_marqueeWin, strTrace)
        scrap += "YWAVE:" + GetWavesDataFolder(w,4) + ";" + TraceInfo(S_marqueeWin, strTrace, 0)
    endfor
    PutScrapText scrap
end

static function PasteTraces()
    string scrap = GetScrapText()
    int start = 0, stop = 0
    int replaceAxes = 0
   
    if (GetKeyState(0) & 2) // option/alt
        // choose axes
        GetLastUserMenuInfo
        string axis = "", hAxis = "", vAxis = "", flags = ""
        string strAxes = AxisList(S_graphName), hList = "bottom;top;", vList = "left;right;", type = "", info = ""
        int i, isHorizontal
        Make/D/free/N=3 wAx // free wave to hold axis minimum, maximum, axis value for mouse location
        for (i=ItemsInList(strAxes);i>=0;i--)
            axis = StringFromList(i, strAxes)
            info = AxisInfo(S_graphName, axis)
            type = StringByKey("AXTYPE", info)
            isHorizontal = (cmpstr(type, "bottom")==0 || cmpstr(type,"top")==0)
            isHorizontal = isHorizontal || (cmpstr(type[0,2],"/B=")==0 || cmpstr(type[0,2],"/T=")==0)
                   
            GetAxis /W=$S_graphName/Q $axis
            wAx = {v_min, v_max, AxisValFromPixel(S_graphName, axis, isHorizontal ? V_mouseX : V_mouseY)}
            if (WaveMax(wAx) == wAx[2] || WaveMin(wAx) == wAx[2])
                continue
            endif
                       
            if (isHorizontal)
                if (FindListItem(axis, hList) < 0)
                    hList = AddListItem(axis, hList)
                endif
            else
                if (FindListItem(axis, vList) < 0)
                    vList = AddListItem(axis, vList)
                endif
            endif
        endfor
       
        Prompt vAxis, "Vertical Axis", Popup, vList
        Prompt hAxis, "Horizontal Axis", Popup, hList
        DoPrompt "Select Axes", vAxis, hAxis
       
        if (V_flag || cmpstr(vAxis, "_none_") == 0 || cmpstr(hAxis, "_none_") == 0)
            return 0
        endif
       
        if (cmpstr(hAxis, "top") == 0)
            flags += "/T"
        else
            info = AxisInfo(S_graphName, vAxis)
            flags += StringByKey("AXFLAG", info)
        endif
        if (cmpstr(vAxis, "right") == 0)
            flags += "/R"
        else
            info = AxisInfo(S_graphName, hAxis)
            flags += StringByKey("AXFLAG", info)
        endif
       
        replaceAxes = 1
       
    endif
   
    string cmd = ""
   
    do
        start = strsearch(scrap, "YWAVE:", stop)
        if (start<0)
            return 0
        endif
        stop = strsearch(scrap, "YWAVE:", start + 1)
        stop = stop<0 ? strlen(scrap) - 1 : stop - 1
       
        cmd = scrap[start,stop]

        if (replaceAxes)
            cmd = ReplaceStringByKey("YAXIS", cmd, vAxis)
            cmd = ReplaceStringByKey("XAXIS", cmd, hAxis)
            cmd = ReplaceStringByKey("AXISFLAGS", cmd, flags)
        endif
       
        PasteTrace(cmd)
    while(1)
end

static function PasteTrace(string info)
    string s = "", cmd = "AppendToGraph"//, info = GetScrapText()
    cmd += StringByKey("AXISFLAGS", info, ":", ";") + " "
    cmd += StringByKey("YWAVE", info, ":", ";") + StringByKey("YRANGE", info, ":", ";")
    s = StringByKey("XWAVE", info, ":", ";")
    if (strlen(s))
        cmd += " vs " + StringByKey("XWAVEDF", info, ":", ";") + s + StringByKey("XRANGE", info, ":", ";")
    endif
    Execute cmd
   
    s = StringByKey("ERRORBARS", info, ":", ";")
    if (strlen(s))
        Execute s
    endif

    // figure out trace name, or trace number
    s = TraceNameList("",";",1)
    string tracename = StringFromList(ItemsInList(s)-1, s)
   
    // apply formatting
    s = info[strsearch(info, "RECREATION:", 0) + 11,Inf]
    int i
    int numCmd = ItemsInList(s)
    for (i=0;i<numCmd;i++)
        cmd = StringFromList(i, s)
        if (!stringmatch(cmd, "offset(x)=*"))
            Execute/Q/Z "ModifyGraph "+ReplaceString("(x)", cmd, "("+traceName+")", 0, 1)
        endif
    endfor
end

static function PasteTraceFormatting(int WhichCmds)
    GetLastUserMenuInfo
    string s = GetScrapText(), cmd = ""
    s = s[strsearch(s, "RECREATION:", 0) + 11, Inf]
    int numCmd = ItemsInList(s)
    int i
    for (i=0;i<numCmd;i++)
        cmd = StringFromList(i, s)
        if ((WhichCmds&1) && cmpstr(cmd[0,9], "offset(x)=")==0) // bit 0, offsets
            Execute/Q/Z "ModifyGraph " + ReplaceString("(x)", cmd, "("+S_traceName+")", 0, 1)
        elseif ((WhichCmds&2) && cmpstr(cmd[0,9], "offset(x)="))
            Execute/Q/Z "ModifyGraph " + ReplaceString("(x)", cmd, "("+S_traceName+")", 0, 1)
        endif
    endfor
end

// note that the list will be reverse-ordered, which is useful if you
// want to loop over the list to remove or change trace names.
static function/S TracesInMarquee()
       
    GetMarquee/Z
   
    string strWin = S_marqueeWin
    variable hCentre, vCentre, delX, delY
    vCentre = (v_top + v_bottom) / 2
    hCentre = (v_left + v_right) / 2
    delX = abs(v_right - v_left) / 2
    delY = abs(v_bottom - v_top) / 2
       
    string outlist = "", inlist = TraceNameList(strWin,";",1+4) // excludes hidden traces
    string strTrace = ""
    string strHit = ""
    string strOptions = ""
   
    int i
    int numTraces = ItemsInList(inlist)
    for (i=0;i<numTraces;i++)
        strTrace = StringFromList(i,inlist)
       
        sprintf strOptions, "WINDOW:%s;ONLY:%s;DELTAX:%g;DELTAY:%g;", strWin, strTrace, delX, delY
        strHit = TraceFromPixel(hCentre, vCentre, strOptions)
        if (strlen(strHit) == 0)
            continue
        endif
       
        outlist = AddListItem(strTrace, outlist)
    endfor
       
    return outlist
end

static function SetMQTraceColor()
    GetLastUserMenuInfo // Sets V_Red, V_Green, V_Blue, V_Alpha, S_value, V_value
    string strTraces = TracesInMarquee()
    GetMarquee/Z/K
    int i, imax
    imax = ItemsInList(strTraces)
    for (i=0;i<imax;i++)
        ModifyGraph rgb($StringFromList(i, strTraces))=(V_Red,V_Green,V_Blue,V_Alpha)
    endfor
end

static function HideOrRemoveMQTraces(int hide)
    string strTraces = TracesInMarquee()
    GetMarquee/Z/K
    int i, imax
    imax = ItemsInList(strTraces)
    for (i=0;i<imax;i++)
        if (hide)
            ModifyGraph hideTrace($StringFromList(i, strTraces))=1
        else
            RemoveFromGraph $StringFromList(i, strTraces)
        endif
    endfor
end

 

See WaveMetrics Procedures:Graph Utility Procs.ipf. Includes CopyTraceSettings(), CopyAxisSettings(), CopyImageSettings() and CopyContourSettings().

Has a number of other useful utilities related to getting characteristics of graphs.

It's pretty old. Probably could use some modern polish.

Tony, what happens if the user changed trace parameters from the command line rather than menu?

Tony's right- TraceInfo returns the current state of the data structures. Note that it can return stale info in a function because certain things are updated during drawing, a running function suppresses redrawing. If you use ModifyGraph, SetAxis, etc., in a function, call DoUpdate before TraceInfo.

In reply to by s.r.chinn

I'm realizing that I should have been more clear about how the snippet is used:

right click on a trace and select 'copy trace formatting', then right click on a different trace and select 'paste trace formatting'.

A more useful version might have options to paste offset settings separately from line/marker/color etc.

paste trace formatting, offsets, or the trace itself...

Edit: The most recent version of the code is at the top of this thread

I have added some marquee menus to allow hiding, removing, copying and pasting groups of traces.

Forum

Support

Gallery

Igor Pro 9

Learn More

Igor XOP Toolkit

Learn More

Igor NIDAQ Tools MX

Learn More