Set Values in Marquee to NaN
JimProuty
// https://www.wavemetrics.com/code-snippet/set-values-marquee-nan
// Written 2009-07-23 by Jim Prouty
// Edited 2015-11-06 by Joel Corbin
// Revised 2018-07-19 by Jim Prouty, version 3, added undo, added ActiveGraphWindow() to support subwindows. Omits bar chart traces.
// Adds one menu item per trace to the GraphMarquee menu.
// Selecting one sets only that trace's values which lie inside the marquee to NaN.
// Both Y vs X and waveform traces are supported.
// One-level undo is implemented.
#pragma rtGlobals=1
#pragma version=3 // 2018-07-19, JP
Menu "GraphMarquee", dynamic
Submenu "Set y-axis data within marquee to NaN..."
CommandPerTrace(), /Q, SetMarqueedValuesToNaN()
CommandUndoTrace(), /Q, UndoSetValuesToNaN()
end
End
Function/S CommandPerTrace()
String menuList=""
String graphName=ActiveGraphWindow()
String traceList=TraceNameList(graphName,";",1+4) // only visible non-contour, non-box, non-violin traces
Variable i, n= ItemsInList(traceList)
for(i=0; i<n; i+= 1)
String traceName= StringFromList(i,traceList)
String info= TraceInfo(graphName, traceName, 0)
// skip traces with text X waves (bar charts)
String xWaveName= StringByKey("XWAVE", info)
WAVE/Z wx = $xWaveName
Variable wt= WaveType(wx,1)
if( wt == 0 || wt == 1 )
menuList += "Set "+traceName+" y-data to NaN;"
endif
endfor
return menuList
End
Function/S CommandUndoTrace()
String menuList=""
String graphName=ActiveGraphWindow()
String traceName
WAVE/Z backupWave= HaveTraceBackupForGraph(graphName, traceName)
if( WaveExists(backupWave) ) // see if the trace is still on the graph
Wave/Z wy= TraceNameToWaveRef(graphName,traceName)
CheckDisplayed/W=$graphName wy
if( V_Flag )
menuList += "Undo setting "+traceName+" y-data to NaN;"
endif
endif
return menuList
End
static Function/S ActiveGraphWindow()
String graphName=""
String hostWindow=WinName(0,1+4+64) // top-level window, could be a panel or layout containing an embedded graph subwindow
if( strlen(hostWindow) )
GetWindow $hostWindow activeSW
graphName= S_Value // Graph0:subWindow
endif
return graphName
End
Function SetMarqueedValuesToNaN()
GetLastUserMenuInfo
String traceName
sscanf S_value, "Set %s y-data to NaN", traceName
String graphName= ActiveGraphWindow()
Wave/Z wy= TraceNameToWaveRef(graphName,traceName)
if( !WaveExists(wy) )
DoAlert 0, "Trace "+traceName+" could not be found"
return -1
endif
String info= TraceInfo(graphName, traceName, 0)
String hAxis= StringByKey("XAXIS", info)
String vAxis= StringByKey("YAXIS", info)
GetMarquee/W=$graphName/K $hAxis, $vAxis
Variable xMin= min(V_right, V_left)
Variable xMax= max(V_right, V_left)
Variable yMin= min(V_top, V_bottom)
Variable yMax= max(V_top, V_bottom)
// Save backup of wy for Undo
SaveTraceBackup(graphName, traceName, wy)
// make a mask wave indicating points which lie within the marquee
// then multiply it with the y (and possibly x) wave
String maskName=UniqueName("mask",1,0)
Duplicate/O wy, $maskName
WAVE mask = $maskName
Wave/Z wx = XWaveRefFromTrace(graphName,traceName)
if( WaveExists(wx) ) // Y vs x
mask = (wy > yMin) && (wy < yMax) && (wx > xMin) && (wx < xMax) ? NaN : 1
else // just a waveform, use X scaling
mask = (wy > yMin) && (wy < yMax) && (pnt2x(wy,p) > xMin) && (pnt2x(wy,p) < xMax) ? NaN : 1
endif
wy *= mask
KillWaves/Z mask
End
static Function SaveTraceBackup(graphName, traceName, wy)
String graphName, traceName
Wave wy
NewDataFolder/O root:Packages
NewDataFolder/O root:Packages:SetMarqueeValuesToNaN
Duplicate/O wy, root:Packages:SetMarqueeValuesToNaN:backupForUndo
String/G root:Packages:SetMarqueeValuesToNaN:graphName = graphName
String/G root:Packages:SetMarqueeValuesToNaN:traceName = traceName
End
static Function/WAVE HaveTraceBackupForGraph(graphName, traceName)
String graphName // input
String &traceName // output
WAVE backupWave // null
DFREF dfr = root:Packages:SetMarqueeValuesToNaN
if (DataFolderRefStatus(dfr) != 0)
SVAR/Z backupGraphName= dfr:graphName
SVAR/Z backupTraceName= dfr:traceName
WAVE/Z backupYwave= dfr:backupForUndo
Variable haveBackup = CmpStr(graphName, backupGraphName) == 0 && strlen(backupTraceName) && WaveExists(backupYwave)
if( haveBackup )
WAVE backupWave= backupYwave
traceName= backupTraceName
endif
endif
return backupWave // output
End
Function UndoSetValuesToNaN()
String graphName= ActiveGraphWindow()
GetMarquee/W=$graphName/K
String traceName
WAVE/Z backupWave= HaveTraceBackupForGraph(graphName, traceName)
if( !WaveExists(backupWave) ) // see if the trace is still on the graph
DoAlert 0, "Undo Wave for "+traceName+" could not be found"
return -1
endif
WAVE/Z wy= TraceNameToWaveRef(graphName,traceName)
if( !WaveExists(wy) )
DoAlert 0, "Trace "+traceName+" wave could not be found"
return -1
endif
// Undo
wy= backupWave[p]
// Remove Undo backup
KillDataFolder/Z root:Packages:SetMarqueeValuesToNaN
return 0 // success
End
// Written 2009-07-23 by Jim Prouty
// Edited 2015-11-06 by Joel Corbin
// Revised 2018-07-19 by Jim Prouty, version 3, added undo, added ActiveGraphWindow() to support subwindows. Omits bar chart traces.
// Adds one menu item per trace to the GraphMarquee menu.
// Selecting one sets only that trace's values which lie inside the marquee to NaN.
// Both Y vs X and waveform traces are supported.
// One-level undo is implemented.
#pragma rtGlobals=1
#pragma version=3 // 2018-07-19, JP
Menu "GraphMarquee", dynamic
Submenu "Set y-axis data within marquee to NaN..."
CommandPerTrace(), /Q, SetMarqueedValuesToNaN()
CommandUndoTrace(), /Q, UndoSetValuesToNaN()
end
End
Function/S CommandPerTrace()
String menuList=""
String graphName=ActiveGraphWindow()
String traceList=TraceNameList(graphName,";",1+4) // only visible non-contour, non-box, non-violin traces
Variable i, n= ItemsInList(traceList)
for(i=0; i<n; i+= 1)
String traceName= StringFromList(i,traceList)
String info= TraceInfo(graphName, traceName, 0)
// skip traces with text X waves (bar charts)
String xWaveName= StringByKey("XWAVE", info)
WAVE/Z wx = $xWaveName
Variable wt= WaveType(wx,1)
if( wt == 0 || wt == 1 )
menuList += "Set "+traceName+" y-data to NaN;"
endif
endfor
return menuList
End
Function/S CommandUndoTrace()
String menuList=""
String graphName=ActiveGraphWindow()
String traceName
WAVE/Z backupWave= HaveTraceBackupForGraph(graphName, traceName)
if( WaveExists(backupWave) ) // see if the trace is still on the graph
Wave/Z wy= TraceNameToWaveRef(graphName,traceName)
CheckDisplayed/W=$graphName wy
if( V_Flag )
menuList += "Undo setting "+traceName+" y-data to NaN;"
endif
endif
return menuList
End
static Function/S ActiveGraphWindow()
String graphName=""
String hostWindow=WinName(0,1+4+64) // top-level window, could be a panel or layout containing an embedded graph subwindow
if( strlen(hostWindow) )
GetWindow $hostWindow activeSW
graphName= S_Value // Graph0:subWindow
endif
return graphName
End
Function SetMarqueedValuesToNaN()
GetLastUserMenuInfo
String traceName
sscanf S_value, "Set %s y-data to NaN", traceName
String graphName= ActiveGraphWindow()
Wave/Z wy= TraceNameToWaveRef(graphName,traceName)
if( !WaveExists(wy) )
DoAlert 0, "Trace "+traceName+" could not be found"
return -1
endif
String info= TraceInfo(graphName, traceName, 0)
String hAxis= StringByKey("XAXIS", info)
String vAxis= StringByKey("YAXIS", info)
GetMarquee/W=$graphName/K $hAxis, $vAxis
Variable xMin= min(V_right, V_left)
Variable xMax= max(V_right, V_left)
Variable yMin= min(V_top, V_bottom)
Variable yMax= max(V_top, V_bottom)
// Save backup of wy for Undo
SaveTraceBackup(graphName, traceName, wy)
// make a mask wave indicating points which lie within the marquee
// then multiply it with the y (and possibly x) wave
String maskName=UniqueName("mask",1,0)
Duplicate/O wy, $maskName
WAVE mask = $maskName
Wave/Z wx = XWaveRefFromTrace(graphName,traceName)
if( WaveExists(wx) ) // Y vs x
mask = (wy > yMin) && (wy < yMax) && (wx > xMin) && (wx < xMax) ? NaN : 1
else // just a waveform, use X scaling
mask = (wy > yMin) && (wy < yMax) && (pnt2x(wy,p) > xMin) && (pnt2x(wy,p) < xMax) ? NaN : 1
endif
wy *= mask
KillWaves/Z mask
End
static Function SaveTraceBackup(graphName, traceName, wy)
String graphName, traceName
Wave wy
NewDataFolder/O root:Packages
NewDataFolder/O root:Packages:SetMarqueeValuesToNaN
Duplicate/O wy, root:Packages:SetMarqueeValuesToNaN:backupForUndo
String/G root:Packages:SetMarqueeValuesToNaN:graphName = graphName
String/G root:Packages:SetMarqueeValuesToNaN:traceName = traceName
End
static Function/WAVE HaveTraceBackupForGraph(graphName, traceName)
String graphName // input
String &traceName // output
WAVE backupWave // null
DFREF dfr = root:Packages:SetMarqueeValuesToNaN
if (DataFolderRefStatus(dfr) != 0)
SVAR/Z backupGraphName= dfr:graphName
SVAR/Z backupTraceName= dfr:traceName
WAVE/Z backupYwave= dfr:backupForUndo
Variable haveBackup = CmpStr(graphName, backupGraphName) == 0 && strlen(backupTraceName) && WaveExists(backupYwave)
if( haveBackup )
WAVE backupWave= backupYwave
traceName= backupTraceName
endif
endif
return backupWave // output
End
Function UndoSetValuesToNaN()
String graphName= ActiveGraphWindow()
GetMarquee/W=$graphName/K
String traceName
WAVE/Z backupWave= HaveTraceBackupForGraph(graphName, traceName)
if( !WaveExists(backupWave) ) // see if the trace is still on the graph
DoAlert 0, "Undo Wave for "+traceName+" could not be found"
return -1
endif
WAVE/Z wy= TraceNameToWaveRef(graphName,traceName)
if( !WaveExists(wy) )
DoAlert 0, "Trace "+traceName+" wave could not be found"
return -1
endif
// Undo
wy= backupWave[p]
// Remove Undo backup
KillDataFolder/Z root:Packages:SetMarqueeValuesToNaN
return 0 // success
End
Forum
Support
Gallery
Igor Pro 9
Learn More
Igor XOP Toolkit
Learn More
Igor NIDAQ Tools MX
Learn More
change
to
GetMarquee
String graphName= S_marqueeWin
October 28, 2016 at 02:31 pm - Permalink
Hello, the code works great. Do you know how to amend it to work for an image plot?
I have a matrix that acts as the Z wave, and two 1D waves that act as the X and Y wave respectively.
July 19, 2018 at 03:53 am - Permalink
In reply to by MGHuber
I've made changes to the revised snippet to handle subwindow graphs. And added Undo.
July 19, 2018 at 01:49 pm - Permalink