Separate graphing of groups of rows within a single wave

My datasets tend to be of the "x, y, treatment" type, where x is some numerical covariate of y, and I need to graph/analyze the data by treatment on a single graph.
Thus, Y and X are typically single columns of data, with treatment defining to which group those data belong.

Is there a (easy; yes I know I am lazy) way to graph the single y wave against x, group by treatment, and then allow, for example, curve fitting for all rows belonging to a group?
See attached image for an impression of what I am looking for visually. The three colors represent different treatments.

My next option is to write some scripts that allow the use of subsets of rows within the single waves for further procedures, but I thought I'd see if I have missed something obvious.

Thanks for any insights.
-Ruud
RJS wrote:

Is there a (easy; yes I know I am lazy) way to graph the single y wave against x, group by treatment, and then allow, for example, curve fitting for all rows belonging to a group?


Have I understood correctly when you write 'single y wave against x' that you are dealing with only one dimensional waves: xwave, ywavetreatment1, ywavetreatment2, etc.? In that case, one way to organize your workflow is to choose wave names (or wave notes) that can understood by your scripts. Then you would build a list of wavenames for further analysis, either by parsing the names or through user input, and loop through that list applying some kind of processing? I think you'll need to be a bit more specific about the format of your data and what you're trying to achieve if you're looking for more specific suggestions than that.


I reread your post and I think I see now how your data are arranged: you have an x and y wave that contain multiple sequences ('treatments') of data, with a third wave that labels the ranges of points that make up a particular treatment. So in your example plot the colored traces represent three different point ranges of xwave and ywave. To curve fit an individual treatment, you would use a mask wave to fit one treatment at a time. Set the points of the maskwave corresponding to a treatment to 1 and the others to 0. Use the /M=maskWaveName flag for CurveFit. You can set set trace properties (color or whatever) by treatment type using f(z) in the modify trace dialog, or use the equivalent ModifyGraph operation.



This is not easy. Or it is. Are you willing to code something?

* Graphing: Use treatment as a definition of marker color or type. You may need to code something to replace the ASCII text with a suitable marker. One approach would be to create a marker wave and then do this step as many times as needed ...

wmarker[]  =(cmpstr(wtreatment[p],"hot")) == 1 ? 0 : 1


--> This approach will not give any "connect the dots" lines. When you insist that you want them as well, you must separate your x,y,treatment triple into as many x,y wave pairs as you have different treatments.

* Analyzing: The hard way is to write an all-at-once-fit function that handles your single x,y,treatment triple as a single wave. The easy way is to separate the x,y,treatment triple in to as many x,y wave pairs as you have different treatments.

For an example of the output from an all-at-once-fit-function approach, see the last figure in my publication here ...

Surfaces and Interfaces - Gailliard, Maharanwar, Weimer, and Williams

Unless you absolutely must extract the same parameters from all inputs regardless of treatment, I would advise to avoid this path.

--
J. J. Weimer
Chemistry / Chemical & Materials Engineering, UAH
This might be a good feature for IP8.

Another analysis program I use very frequently is JMP and the features it has that could act as basis.

With a graph I can select marker by column (where column is their term for 1D wave). This color/marker codes based on a wave without the need to create a specific coding column. They call it row legend. The column(wave) can be either numeric or text (ordinal/nominal).

The other really nice feature is in fitting. There is option to "group by" and again a column (wave) is used to identify. When I then select curve fit to a line (for example) I will get n fits where n is the number of unique levels in the column/wave.

Andy
Base.png (122.57 KB) Row Legend.png (183.93 KB) With Fit.png (214.36 KB)
Thanks for all the replies!
I managed to come up with a way to do this using my original table as (somewhat vaguely it seems ;) described earlier.
However, its is still a multistep process...

Funny you should mention JMP; this is what I use all the time to generate the types of tables in question.

Anyway, I basically re-purposed parts of a script of a friend of mine once gave me and created a small do/while loop that chops the single data waves into subset waves (for lack of a better word), which I then can plot, and use the "Waves Average Panel" to get at what I want. Its a specific solution to my problem, but perhaps it is useful..

Here is the "script"; apologies for not putting this in the right format (probably); this is the first time I actually post code.
Macro SeparateWaves()
    Variable counter, counter2
    String prefix, suffix, wavename1, wavename2, wavename3,
    counter=0
    counter2=0
    do                             
        prefix=num2str(specimen_ID[counter])    //specimen_ID are referring to animals I take my measurements from
        suffix=status[counter]              //status refers to the "treatment"
        //this should allow you to move through these categorical (text) waves and attach specimen ID,
        //and status to the mini-waves; by increasing this counter with the number of measurements for each individual
        wavename1="_y1_"    //y1 refers to whatever measurement wave of interest
        wavename2="_y2_"    //y2 refers to another measurement wave of interest if needed
        wavename3="_x1_"    //x1 refers to whatever covariate wave of interest (this is the same for all individuals measured in this particular example)
        Make/N=26/D $(prefix+wavename1+suffix) $(prefix+wavename1+suffix) = y1[p+counter2]
        Make/N=26/D $(prefix+wavename2+suffix) $(prefix+wavename2+suffix) = y2[p+counter2]
        Make/N=26/D $(prefix+wavename3+suffix) $(prefix+wavename3+suffix) = x1[p+counter2]
        //sofar so good
        //when needed, do calculations on these mini-waves and then move the counter along the datawaves
        counter+=26
        counter2+=26
        //and do it again
    while (counter<total length of datawave)
    //at this point you will have a multitude of small waves that you can plot on the same graph, with the same x-axis 
    //followed by some batch curve fitting procedure on the treatment subsets?
    //extraction of fitted curve and some fancy plotting?
Endmacro

[JimProuty added <igor> tags around the code]
Hi,

Here is what I cobbled together with the idea of creating a wave to match the text wave with the ids that can be used for color and/or marker f(z) options in graphing. This has some limitations in that if lines and markers are used then different id's would be connected. If this is a problem one option would be to sort and then insert points with NaN values.

It takes a text wave as input and creates a marker wave with a numeric value for each unique text value.

Function MakeKey(TextWave)
    Wave /T TextWave
   
    Findduplicates/FREE /RT=Keylist Textwave
    Make /O /n=(numpnts(textwave)) MarkerKey
    VAriable index,maxindex
    maxindex = numpnts(keylist)
    for(index=0;index<maxindex;index+=1)
        MarkerKey = stringmatch(Textwave,Keylist[index])? index : MarkerKey
    endfor 
   

End


Andy
RJS wrote:
...created a small do/while loop that chops the single data waves into subset waves (for lack of a better word), which I then can plot, and use the "Waves Average Panel" to get at what I want.

I'm not sure what you are doing with Waves Average, but both graphs and the CurveFit/FuncFit commands accept wave subranges. That might allow you to avoid the chopping part, and the extra waves that come along with it.

If you need to average together several of the chopped bits, then your approach seems like the best one.

John Weeks
WaveMetrics, Inc.
support@wavemetrics.com