XYIntervalSeriesCollection xyDataset = new XYIntervalSeriesCollection();
if (history != null) {
// add actual historical data values
for (String targetName : targetNames) {
XYIntervalSeries targetSeries = new XYIntervalSeries(targetName, false,
false);
xyDataset.addSeries(targetSeries);
}
}
// add predicted series
for (String targetName : targetNames) {
XYIntervalSeries targetSeries = new XYIntervalSeries(targetName
+ "-predicted", false, false);
xyDataset.addSeries(targetSeries);
}
ValueAxis timeAxis = null;
NumberAxis valueAxis = new NumberAxis("");
valueAxis.setAutoRangeIncludesZero(false);
int timeIndex = -1;
boolean timeAxisIsDate = false;
double artificialTimeStart = 0;
double lastRealTimeValue = Utils.missingValue();
if (forecaster instanceof TSLagUser && history != null) {
TSLagMaker lagMaker = ((TSLagUser) forecaster).getTSLagMaker();
if (!lagMaker.isUsingAnArtificialTimeIndex()
&& lagMaker.getAdjustForTrends()) {
String timeName = lagMaker.getTimeStampField();
if (history.attribute(timeName).isDate()) {
timeAxis = new DateAxis("");
timeAxisIsDate = true;
timeIndex = history.attribute(timeName).index();
}
} else {
try {
artificialTimeStart = (history != null) ? 1 : lagMaker
.getArtificialTimeStartValue() + 1;
} catch (Exception ex) {
}
}
}
if (timeAxis == null) {
timeAxis = new NumberAxis("");
((NumberAxis) timeAxis).setAutoRangeIncludesZero(false);
}
boolean hasConfidenceIntervals = false;
// now populate the series
if (history != null) {
// do the actuals first
for (int i = 0; i < history.numInstances(); i++) {
Instance current = history.instance(i);
for (String targetName : targetNames) {
int dataIndex = history.attribute(targetName.trim()).index();
if (dataIndex >= 0) {
XYIntervalSeries actualSeries = null;
int actualIndex = xyDataset.indexOf(targetName);
actualSeries = xyDataset.getSeries(actualIndex);
double x = Utils.missingValue();
if (timeAxisIsDate) {
x = current.value(timeIndex);
if (!Utils.isMissingValue(x)) {
lastRealTimeValue = x;
}
} else {
x = artificialTimeStart;
}
double y = Utils.missingValue();
y = current.value(dataIndex);
if (!Utils.isMissingValue(x) && !Utils.isMissingValue(y)) {
if (actualSeries != null) {
actualSeries.add(x, x, x, y, y, y);
}
}
}
}
if (!timeAxisIsDate) {
artificialTimeStart++;
}
}
}
// now do the futures
List<String> forecasterTargets = AbstractForecaster.stringToList(forecaster
.getFieldsToForecast());
// loop over the steps
for (int j = 0; j < preds.size(); j++) {
List<NumericPrediction> predsForStepJ = preds.get(j);
// advance the real time index (if appropriate)
if (timeAxisIsDate) {
lastRealTimeValue = ((TSLagUser) forecaster).getTSLagMaker()
.advanceSuppliedTimeValue(lastRealTimeValue);
}
for (String targetName : targetNames) {
// look up this requested target in the list that the forecaster
// has predicted
int predIndex = forecasterTargets.indexOf(targetName.trim());
if (predIndex >= 0) {
NumericPrediction predsForTargetAtStepJ = predsForStepJ
.get(predIndex);
XYIntervalSeries predSeries = null;
int datasetIndex = xyDataset.indexOf(targetName + "-predicted");
predSeries = xyDataset.getSeries(datasetIndex);
if (predSeries != null) {
double y = predsForTargetAtStepJ.predicted();
double x = Utils.missingValue();
double yHigh = y;
double yLow = y;
double[][] conf = predsForTargetAtStepJ.predictionIntervals();
if (conf.length > 0) {
yLow = conf[0][0];
yHigh = conf[0][1];
hasConfidenceIntervals = true;
}
if (!timeAxisIsDate) {
x = artificialTimeStart;
} else {
x = lastRealTimeValue;
}
if (!Utils.isMissingValue(x) && !Utils.isMissingValue(y)) {
predSeries.add(x, x, x, y, yLow, yHigh);
}
}
}
}
// advance the artificial time index (if appropriate)
if (!timeAxisIsDate) {
artificialTimeStart++;
}
}
String title = "Future forecast for: ";
for (String s : targetNames) {
title += s + ",";
}
title = title.substring(0, title.lastIndexOf(","));
/*
* String algoSpec = forecaster.getAlgorithmName(); title += " (" + algoSpec
* + ")";
*/
if (forecaster instanceof WekaForecaster && hasConfidenceIntervals) {
double confPerc = ((WekaForecaster) forecaster).getConfidenceLevel() * 100.0;
title += " [" + Utils.doubleToString(confPerc, 0) + "% conf. intervals]";
}
XYErrorRenderer renderer = new XYErrorRenderer();
// renderer.setShapesFilled(true);
XYPlot plot = new XYPlot(xyDataset, timeAxis, valueAxis, renderer);
// renderer = (XYErrorRenderer)plot.getRenderer();
if (history != null) {
for (String targetName : targetNames) {
XYIntervalSeries predSeries = null;
int predIndex = xyDataset.indexOf(targetName + "-predicted");
predSeries = xyDataset.getSeries(predIndex);
XYIntervalSeries actualSeries = null;
int actualIndex = xyDataset.indexOf(targetName);
actualSeries = xyDataset.getSeries(actualIndex);
if (actualSeries != null && predSeries != null) {
// match the color of the actual series