|
multiple Trend Lines in one Chart |
Posted by slaniwani on Jan-18-2011 20:51 |
|
Hi Guys,
I have a problem with multiple Trend Lines for given periods.
It the screenshot you see 4 periods and I want to have a trend Line for each period.
I use this code :
trendlayer1 = c.addTrendLayer2(time_periods[0],value_periods[0], '0x0000ff')
trendlayer1.setLineWidth(3)
trendlayer1.setRegressionType(LinearRegression)
trendlayer1.addConfidenceBand(0.30, '0x806666ff')
trendlayer1.addPredictionBand(0.30, '0x8066ff66')
c.addTrenLayer2(xData, yData) should be clear but why does it draws the line over the whole plot erea. I only want to draw the line for this given period.
|
Re: multiple Trend Lines in one Chart |
Posted by Peter Kwan on Jan-19-2011 02:21 |
|
Hi slaniwani,
The trend lines are not automatically bounded by the x-coordinates of your data, just like they are not bounded by the y-coordinates of your data.
The most common reason of using trend lines are to obtain the line parameters (slope and intercept), and/or to perform predictions or extrapolation (eg. what will be the speed of the CPU if the "current trend" continues for the next 10 years)? In these common usages, a trend line should be extended for the whole x-axis and y-axis range.
If you just want a trend line (or any other chart object) to appear only within certain x-axis range, you may use a xZoneColor. For example:
#color = '0x0000ff' if t1 <= x <= t2, otherwise it is transparent
lineColor = c.xZoneColor(t1, Transparent, c.xZoneColor(t2, '0x0000ff', Transparent))
trendlayer1 = c.addTrendLayer2(time_periods[0],value_periods[0], lineColor)
You would need to use similar methods to configure your confidence and prediction band colors too.
Hope this can help.
Regards
Peter Kwan |
Re: multiple Trend Lines in one Chart |
Posted by slaniwani on Jan-19-2011 16:12 |
|
Good morning Peter,
thank you for your great help!
Maybe you good give me one more advice for comparing trend lines.
In this image you see smoothed values(blue line) and I build a linear regression for this Trend.
Now I want to compare this one to another trend line(not included yet) from a different period and see if it differs strongly to the trend before.
You know what I mean?
Thanks for your help,
Daniel
|
Re: multiple Trend Lines in one Chart |
Posted by slaniwani on Jan-19-2011 16:15 |
|
Sorry for double post , but I have to meantion the comparison particulartly :
It should not be only visually, I want to compare the trends and give some alert, if it differs strongly. |
Re: multiple Trend Lines in one Chart |
Posted by Peter Kwan on Jan-19-2011 18:53 |
|
Hi slaniwani,
ChartDirector can provide your code with the slope and intercept of the trend line (see TrendLayer.getSlope and TrendLayer.getIntercept). If you think the slopes and intercepts differ by too much, your code can add more things to the chart, just as a custom text box (see BaseChart.addText) with some alert text.
Hope this can help.
Regards
Peter Kwan |
Re: multiple Trend Lines in one Chart |
Posted by DC Kelley on Mar-24-2011 09:10 |
|
Peter said:
> If you just want a trend line (or any other chart object) to appear only within certain
> x-axis range, you may use a xZoneColor. For example:
> #color = '0x0000ff' if t1 <= x <= t2, otherwise it is transparent
> lineColor = c.xZoneColor(t1, Transparent, c.xZoneColor(t2, '0x0000ff', Transparent))
> trendlayer1 = c.addTrendLayer2(time_periods[0],value_periods[0], lineColor)
I see how this would work for a single period of use, but could it also be used for multiple periods in the same graph?
Further, if one were to re-compute a trend for every period, does this mean you would end up with 4 trend layers in the chart you could then code to appear for each period each with if own times/color/etc? I presume one can limit the data used in the developing the trend as needed from the data set as well? The data in the original post is certainly not ergodic in these periods so I presume he wished make some kind of Markov model for his use.
If a more exotic "trend" algorithm were needed, I presume we simply develop it ourselves, and plot the band with other methods like the inter-line coloring example? |
Re: multiple Trend Lines in one Chart |
Posted by Peter Kwan on Mar-24-2011 11:50 |
|
Hi DC Kelley,
If you have multiple periods and have a trend line for each period, it means the trend lines are all using different data. So you just need to repeat the code for a single period multiple times, using different data.
You can limit the data to be used in a trend layer by passing only the data you want to plot to ChartDirector. For example, in C++, suppose your data is DoubleArray(myData, len). If you want a trend layer that only uses data from the 12th point to the 20th point inclusive, then please pass DoubleArray(myData + 12, 9).
The algorithm used in the trend layer is a standard statistical method called "regression". ChartDirector currently only supports linear, exponential, logarithmic, and polynomial regression.
You can certainly use different algorithms. After you have computed the line, you can pass the points along the line to ChartDirector to plot it (using a normal line layer, spline layer, interline layer, etc).
Hope this can help.
Regards
Peter Kwan |
Re: multiple Trend Lines in one Chart |
Posted by DC Kelley on Mar-24-2011 12:30 |
|
> If you have multiple periods and have a trend line for each period, it means the
> trend lines are all using different data. So you just need to repeat the code for
> a single period multiple times, using different data.
So I take it from this we have little control over the section if the date data set used in the trend. If I were to use the line slaniwani proposed of [ trendlayer1 = c.addTrendLayer2(time_periods[0],value_periods[0], '0x0000ff') ] and stuff [NoValue] entries in the data point we did not want considered, how would those 'non' values be treated? Could I effectively limit the data set being considered, yet align it in the sequence of the overall X axis?
From what I know this seem reasonable, but would like to confirm. Said another way, so given a large data array with 'no values' and a few hundred valid points in the middle would result in this set used in the calculation, which in turn would be displayed over a fairly limited period of time around that data (yes, I know it will diverge further away). I am trying to get some short term crude predictive value/trends/slopes from this, which we would then compare (with an interline to plot it) to some better data.
Aside:
Our own work is all done with MATLAB m models, and as you might expect has lots of matrix math and many peculiar details I do not expect ChartDirector to duplicate. But the CD basic features are just great for giving both a gross picture of the effects, and also showing how using a classic "basic" approach for interpolation and extrapolation fall short of the more advanced solutions that have an additional awareness of the underlying process model (no disrespect intended by that, what CD gives is just ideal for showing this).
This is the first tool I have found that will let me clearly the show in various useful ways the 'divergence' bands that various alternative approaches have so that others (typically also mathematically literate folks) can get a feel for the best choice for a given need. |
Re: multiple Trend Lines in one Chart |
Posted by Peter Kwan on Mar-25-2011 00:38 |
|
Hi DC Kelley,
If you use addTrendLayer2 to draw a trend layer, you can pass only the points you want to use to compute the trend line to ChartDirector. For example, if you have 1000 data points, and you only want to use the middle 100 data points to compute the trend line, you can pass only the middle 100 data points to ChartDirector. This is particularly convenient in C++ as no additional line of code is needed to get the middle 100 points.
If for some reasons, your code must pass an array of 1000 values to ChartDirector, your code would need to fill the unnecessary positions with Chart::NoValue, so that ChartDirector knows it needs to ignore these positions.
After computing the trend line, ChartDirector will need to plot the trend line. For example, suppose using the middle 100 points and linear regression, ChartDirector has computed the trend line is "y = 45x + 23". ChartDirector will then plot the line "y = 45x + 23" in the plot area. The end points of the trend line can touch the left and right edges of the plot area, or the top and bottom edges (if the trend line is nearly vertical), or some other combinations.
If you want the trend line end points to be bounded by certain x axis range, you would need to use the xZoneColor method.
So for your case, if you would like to plot a trend line using a certain range of data, and show the trend line only within the same x-axis range, you would need to pass the data in the give range to ChartDirector to compute the trend line, then use an x-zone color to ensure the trend line is plotted only within the x-axis range.
Hope this can help.
Regards
Peter Kwan |
Re: multiple Trend Lines in one Chart |
Posted by DC Kelley on Mar-25-2011 04:44 |
|
I think I have it now (see code and image below) and as always thanks for prompt and useful replies.
The odd thing is that ALL the slope values on the tool tips are all zero, even though the data obviously has slope.
One further gripe, the legend for the shorter period trend layer has some issues. Because the line style used will vary, it seems to have an impact on what line is then used in the legend key. In the image below you can see the 3rd "shortened" slope ("SV12-PrtSlope") is showing this (no line is present), while the other two show a blue line.
If I re-size the image it may or may not have a line. It seems to me that the legend drawing logic looks to what the layer is doing directly underneath it to determine what line type to use, and this creates this issue. What's up and how can I control it?
--------------
Graph and code fragment that produced based on your recommended method to control the overall plot width of the data set:
}
// the data is now loaded to the array, place in the new layer
// add the name of the SV to the layer / dataset
pLayer->addDataSet(DoubleArray(pData, howMany), -1, name);
// now we can use the same data for other interesting layers in the chart as needed
// note that we can never get back to the layer's raw data set once we leave here
// so all layer creation logic needs to be called from here
// TEST #1, Plot full line (line has NoValue points added allready)
TrendLayer *trendLayer = c->addTrendLayer(DoubleArray(pData,howMany), -1, name + "-Slope");
trendLayer->setLineWidth(2);
// tool tip for the trend layer
trendLayer->setHTMLImageMap("", "", "title='{dataSetName} C1/C2 rate: {slope|2} m/s'");
// TEST #2, Plot part of line as per Peter's app note of 03/24
// build simple index of points ~800 where SV12 happens to start a huge run up
// these align with existing X axis with no work on our part
#define startTrend (750)
#define endTrend (850)
#define overhang ((endTrend - startTrend)/2) // 33% beyond source data bounds
int count = endTrend - startTrend;
double* pTimeData;
pTimeData = new double[count];
for (i=0; i<count; i++) pTimeData[i] = i + startTrend;
// now constrain the display color over a limited range
// color = '0x0000ff' if t1 <= x <= t2, otherwise it is transparent
int lineColor = c->xZoneColor((startTrend - overhang), Transparent,
c->xZoneColor((endTrend + overhang),
0x0000ff, Transparent));
// add data and line color to chart as new layer
TrendLayer *trendLayer2 = c->addTrendLayer(DoubleArray(&pTimeData[0], count),
DoubleArray(&pData[startTrend], count),
lineColor, name + "-PrtSlope");
trendLayer2->setLineWidth(2);
trendLayer2->setHTMLImageMap("", "", "title='{dataSetName} C1/C2 rate: {slope|2} m/s'");
|
Re: multiple Trend Lines in one Chart |
Posted by Peter Kwan on Mar-25-2011 14:27 |
|
Hi DC Kelley,
The slope values should not be zero. If the tooltips should show 0.00, it just means the slope is less than 0.005 > slope > -0.005, so it is shown as 0.00 when rounded to 2 decimal place as required by your code. To show the slope (for debugging purpose to see it is really zero), please use {slope} instead of {slope|2}.
For the legend entries, it is usually the same color as the trend layer, which is transparent outside a certain zone. To solve the problem you see, you may need to add two trend layers, one as a dummy just to insert a normal legend entry.
So instead of just using:
TrendLayer *trendLayer2 = c->addTrendLayer(xArray, yArray, anXZonoeColor, name);
trendLayer2->setLineWidth(2);
Please use:
TrendLayer *trendLayer2 = c->addTrendLayer(xArray, yArray, anXZoneColor, name);
trendLayer2->setLineWidth(2);
//disable the original legend entry, and add a new legend entry using a solid color
trendLayer2->setLegendMode(Chart::NoLegend);
c->addTrendLayer(DoubleArray(0, 0), DoubleArray(0, 0), solidColor, name)->setLineWidth(2);
Hope this can help.
Regards
Peter Kwan |
Re: multiple Trend Lines in one Chart |
Posted by DC Kelley on Mar-26-2011 02:43 |
|
Slope worked fine once I allowed 4 digits (and changed meters to cm to get another two), stupid me.
I understand the answer you gave to add a 'fake' trend layer and then use that for the line and label in the legend, but I do not find the method "setLegendMode" for this object and anywhere in the documentation. The constant "NoLegend" does not trace back to this use either.
But in your very excellent examples of code use I found:
// We are not showing the data set name in the legend box. The name is for
// showing in tool tips only.
layer->setLegend(Chart::NoLegend);
That seems to work as described, presume 'mode' was a typo. |
Re: multiple Trend Lines in one Chart |
Posted by Peter Kwan on Mar-26-2011 15:10 |
|
Hi DC Kelley,
Sorry for the mistake. The API should be setLegendOrder.
The setLegend will also work. The setLegend is an older API and is kept for compatibility reasons. It is compatible with the one parameter usage of setLegendOrder. (The setLegendOrder can accept more than 1 parameter.)
Regards
Peter Kwan |
|