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 10

Learn More

Igor XOP Toolkit

Learn More

Igor NIDAQ Tools MX

Learn More