- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Get Direct Link
- Report Inappropriate Content
Difference of lines
Suppose I have two lines, distance vs. time for two different moving objects. The time measurements for object 1 and object 2 are at arbitrary times, i.e., the measured times for object 1 aren't the same times as provided for object 2.
Is there a way in Graph Builder to plot the *difference* between those curves vs. time?
Accepted Solutions
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Get Direct Link
- Report Inappropriate Content
Re: Difference of lines
I think what you want is called a piece-wise linear interpolation. I'm not sure what platform might produce a formula for that, but you can do something similar like this. Do your own testing if you use this!
dt = Open( "$desktop/ab.jmp" ); // table with unaligned times for a and b measurements
dt << sort( by( time ), replacetable( 1 ) ); // make sure time is ascending
aRows = dt << getrowswhere( SourceTable == "a" ); // get all the a
bRows = dt << getrowswhere( SourceTable == "b" ); // and b row indexes
aTimes = dt:time[aRows]; // get all the a and b times and positions in
aPositions = dt:position[aRows]; // matrices for the interpolate function
bTimes = dt:time[bRows];
bPositions = dt:position[bRows];
apos = Function( {time}, // tiny wrappers for interpolate
Interpolate( time, aTimes, aPositions )
);
bpos = Function( {time},
Interpolate( time, bTimes, bPositions )
);
dtnew = New Table( "new_ab", // new table is similar to old table
New Column( "Source Table", Character( 1 ), "Nominal" ),
New Column( "time", Numeric, "Continuous", Format( "Best", 12 ) ),
New Column( "position", Numeric, "Continuous", Format( "Best", 12 ) )
);
bigdif = 0; // track the largest difference so it can have a ref line
bigtime = .;
// make a new table covering the range of the data
For( i = min(min(aTimes),min(bTimes))-10, i <= max(max(aTimes),max(bTimes))+10, i += 1,
dtnew << addrows( 1 ); // interpolate a at time i
dtnew:SourceTable = "a";
dtnew:time = i;
dtnew:position = apos( i );
dtnew << addrows( 1 ); // interpolate b at time i
dtnew:SourceTable = "b";
dtnew:time = i;
dtnew:position = bpos( i );
dtnew << addrows( 1 ); // difference at time i
dtnew:SourceTable = "diff";
dtnew:time = i;
dtnew:position = apos( i ) - bpos( i );
If( Abs( dtnew:position ) > bigdif, // capture biggest diff
bigdif = Abs( dtnew:position );
bigtime = i;
);
);
dtnew << Graph Builder(
Size( 518, 448 ),
Show Control Panel( 0 ),
Variables( X( :time ), Y( :position ), Overlay( :Source Table ) ),
Elements( Points( X, Y, Legend( 21 ) ), Smoother( X, Y, Legend( 22 ), Lambda( 0.000001 ) ) ),
SendToReport(
Dispatch( {}, "time", ScaleBox, {Add Ref Line( bigtime, "Solid", "Black", "big=" || Char( bigtime ), 1 )} ),
Dispatch( {}, "Graph Builder", FrameBox, {Marker Size( 2 )} )
)
);
Input data like this
And the interpolated data like this
Producing a graph like this:
The green curve is blue - red; the ref line is at the first biggest difference.
If this was a race, a won in 71 seconds and b lost in 99 seconds. a was furthest ahead at 43 seconds (well, maybe. You can't be too sure about b's position at time 43 in the original data.)
You can't get that from a simple linear fit on the original data:
Original data with linear fit.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Get Direct Link
- Report Inappropriate Content
Re: Difference of lines
Here's a low scripting alternative using the Save Formula command available in the red triangle menu for a Smoother or Line of Fit element.
Starting with Craige's ab.jmp table using Overlay to get two lines/curves, use Save Formula to get a new column with a formula that looks like:
If( :Source Table == "a", Spline Eval( ... ), :Source Table == "b", Spline Eval( ... ), . ))
Go into the Formula Editor for the new column and change the formula to subtract the two Spline expressions:
Spline Eval( ... ) - Spline Eval( ... )
And use that as the Y in GB.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Get Direct Link
- Report Inappropriate Content
Re: Difference of lines
The only way that you can compare to curves observed at different times is to model each one and compare the models at selected times. The model could be as simple as a linear interpolation as complex as any model type in JMP. Do you have JMP Pro? If so, you can treat the data as 'functions' and use the Functional Data Explorer.
I won't go into detail until I hear from you that the general approach makes sense.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Get Direct Link
- Report Inappropriate Content
Re: Difference of lines
No, we just have the basic JMP v16.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Get Direct Link
- Report Inappropriate Content
Re: Difference of lines
If you had a pair of data tables, one per object, with columns for time and distance, you could save the formulas that would predict positions at between times. Subtracting the formulas at a Time would give an answer. I think Mark's question is if you think a linear/quadratic/other model from Fit Model would give a good-enough estimate of a object position, between measurements.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Get Direct Link
- Report Inappropriate Content
Re: Difference of lines
Exactly. The complexity of the curve or shape will dictate the complexity of the model that is necessary. Can you show a picture of a plot of the data? Perhaps there is a theoretical model for such data?
We cannot help you further because the next step is the modeling, but we have to know which model in order to help you.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Get Direct Link
- Report Inappropriate Content
Re: Difference of lines
@Mark_Bailey wrote:Exactly. The complexity of the curve or shape will dictate the complexity of the model that is necessary. Can you show a picture of a plot of the data? Perhaps there is a theoretical model for such data?
We cannot help you further because the next step is the modeling, but we have to know which model in order to help you.
@Mark_Bailey , @Craige_Hales -- Yes, a linear fit between points would be fine. I realize the difference will be somewhat bouncy due to the linear interpolation, but that's fine, we're just looking at rough magnitudes.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Get Direct Link
- Report Inappropriate Content
Re: Difference of lines
@Mark_Bailey If the two lines are linear, then a Fit Model of Height predicted by Weight, for the 2 sex groups end up having an term estimate of -2.079223. Wouldn't that be the difference between the lines when simplified to a linear regression?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Get Direct Link
- Report Inappropriate Content
Re: Difference of lines
I think what you want is called a piece-wise linear interpolation. I'm not sure what platform might produce a formula for that, but you can do something similar like this. Do your own testing if you use this!
dt = Open( "$desktop/ab.jmp" ); // table with unaligned times for a and b measurements
dt << sort( by( time ), replacetable( 1 ) ); // make sure time is ascending
aRows = dt << getrowswhere( SourceTable == "a" ); // get all the a
bRows = dt << getrowswhere( SourceTable == "b" ); // and b row indexes
aTimes = dt:time[aRows]; // get all the a and b times and positions in
aPositions = dt:position[aRows]; // matrices for the interpolate function
bTimes = dt:time[bRows];
bPositions = dt:position[bRows];
apos = Function( {time}, // tiny wrappers for interpolate
Interpolate( time, aTimes, aPositions )
);
bpos = Function( {time},
Interpolate( time, bTimes, bPositions )
);
dtnew = New Table( "new_ab", // new table is similar to old table
New Column( "Source Table", Character( 1 ), "Nominal" ),
New Column( "time", Numeric, "Continuous", Format( "Best", 12 ) ),
New Column( "position", Numeric, "Continuous", Format( "Best", 12 ) )
);
bigdif = 0; // track the largest difference so it can have a ref line
bigtime = .;
// make a new table covering the range of the data
For( i = min(min(aTimes),min(bTimes))-10, i <= max(max(aTimes),max(bTimes))+10, i += 1,
dtnew << addrows( 1 ); // interpolate a at time i
dtnew:SourceTable = "a";
dtnew:time = i;
dtnew:position = apos( i );
dtnew << addrows( 1 ); // interpolate b at time i
dtnew:SourceTable = "b";
dtnew:time = i;
dtnew:position = bpos( i );
dtnew << addrows( 1 ); // difference at time i
dtnew:SourceTable = "diff";
dtnew:time = i;
dtnew:position = apos( i ) - bpos( i );
If( Abs( dtnew:position ) > bigdif, // capture biggest diff
bigdif = Abs( dtnew:position );
bigtime = i;
);
);
dtnew << Graph Builder(
Size( 518, 448 ),
Show Control Panel( 0 ),
Variables( X( :time ), Y( :position ), Overlay( :Source Table ) ),
Elements( Points( X, Y, Legend( 21 ) ), Smoother( X, Y, Legend( 22 ), Lambda( 0.000001 ) ) ),
SendToReport(
Dispatch( {}, "time", ScaleBox, {Add Ref Line( bigtime, "Solid", "Black", "big=" || Char( bigtime ), 1 )} ),
Dispatch( {}, "Graph Builder", FrameBox, {Marker Size( 2 )} )
)
);
Input data like this
And the interpolated data like this
Producing a graph like this:
The green curve is blue - red; the ref line is at the first biggest difference.
If this was a race, a won in 71 seconds and b lost in 99 seconds. a was furthest ahead at 43 seconds (well, maybe. You can't be too sure about b's position at time 43 in the original data.)
You can't get that from a simple linear fit on the original data:
Original data with linear fit.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Get Direct Link
- Report Inappropriate Content
Re: Difference of lines
Wow, impressive solution! And very well documented, thank you!!
The only thing better would be if JMP just did this on its own without the intermediate scripting step, but aside from shift-clicking two lines in Graph Builder and asking for a difference line (which is conceptually messy from a mental-model-of-what-it's-doing standpoint), I can't really imagine how that would work.
Thanks, Craige!
(ps. Are you really retired? Doing JMP support for fun?)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Get Direct Link
- Report Inappropriate Content
Re: Difference of lines
Yes, retired, and I learn a lot answering questions.
@XanGreggfor the graph builder suggestion.