/**
* Copyright (C) 2001-2017 by RapidMiner and the contributors
*
* Complete list of developers available at our web site:
*
* http://rapidminer.com
*
* This program is free software: you can redistribute it and/or modify it under the terms of the
* GNU Affero General Public License as published by the Free Software Foundation, either version 3
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License along with this program.
* If not, see http://www.gnu.org/licenses/.
*/
package com.rapidminer.gui.viewer.metadata.model;
import java.awt.Color;
import java.util.Arrays;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.StandardXYBarPainter;
import org.jfree.chart.renderer.xy.XYBarRenderer;
import org.jfree.data.statistics.HistogramDataset;
import com.rapidminer.example.Attribute;
import com.rapidminer.example.Example;
import com.rapidminer.example.ExampleSet;
import com.rapidminer.example.Statistics;
import com.rapidminer.gui.tools.AttributeGuiTools;
import com.rapidminer.gui.viewer.metadata.AttributeStatisticsPanel;
import com.rapidminer.tools.Ontology;
/**
* Model for {@link AttributeStatisticsPanel}s which are backed by a numerical {@link Attribute}.
*
* @author Marco Boeck
*
*/
public class NumericalAttributeStatisticsModel extends AbstractAttributeStatisticsModel {
/** the index for the histogram chart */
private static final int INDEX_HISTOGRAM_CHART = 0;
/** the max number of bins */
private static final int MAX_BINS_HISTOGRAM = 10;
/** used to color the chart background invisible */
private static final Color COLOR_INVISIBLE = new Color(255, 255, 255, 0);
/** the average of the numerical values */
private double average;
/** the standard deviation of the numerical values */
private double deviation;
/** the minimum of the numerical values */
private double minimum;
/** the maximum of the numerical values */
private double maximum;
/** array of charts for this model */
private JFreeChart[] chartsArray;
/**
* Creates a new {@link NumericalAttributeStatisticsModel}.
*
* @param exampleSet
* @param attribute
*/
public NumericalAttributeStatisticsModel(ExampleSet exampleSet, Attribute attribute) {
super(exampleSet, attribute);
chartsArray = new JFreeChart[1];
}
@Override
public void updateStatistics(ExampleSet exampleSet) {
average = exampleSet.getStatistics(getAttribute(), Statistics.AVERAGE);
deviation = Math.sqrt(exampleSet.getStatistics(getAttribute(), Statistics.VARIANCE));
minimum = exampleSet.getStatistics(getAttribute(), Statistics.MINIMUM);
maximum = exampleSet.getStatistics(getAttribute(), Statistics.MAXIMUM);
missing = exampleSet.getStatistics(getAttribute(), Statistics.UNKNOWN);
fireStatisticsChangedEvent();
}
/**
* Gets the average of the numerical values.
*
* @return
*/
public double getAverage() {
return average;
}
/**
* Gets the standard deviation of the numerical values.
*
* @return
*/
public double getDeviation() {
return deviation;
}
/**
* Gets the minimum of the numerical values.
*
* @return
*/
public double getMinimum() {
return minimum;
}
/**
* Gets the maximum of the numerical values.
*
* @return
*/
public double getMaximum() {
return maximum;
}
@Override
public JFreeChart getChartOrNull(int index) {
prepareCharts();
if (index == INDEX_HISTOGRAM_CHART) {
return chartsArray[index];
}
return null;
}
/**
* Creates a {@link HistogramDataset} for this {@link Attribute}.
*
* @param exampleSet
* @return
*/
private HistogramDataset createHistogramDataset(ExampleSet exampleSet) {
HistogramDataset dataset = new HistogramDataset();
double[] array = new double[exampleSet.size()];
int count = 0;
for (Example example : exampleSet) {
double value = example.getDataRow().get(getAttribute());
// don't use missing values because otherwise JFreeChart tries to plot them too which
// can lead to false histograms
if (!Double.isNaN(value)) {
array[count++] = value;
}
}
// add points to data set (if any)
if (count > 0) {
// truncate array if necessary
if (count < array.length) {
array = Arrays.copyOf(array, count);
}
dataset.addSeries(getAttribute().getName(), array, Math.min(array.length, MAX_BINS_HISTOGRAM));
}
return dataset;
}
/**
* Creates the histogram chart.
*
* @param exampleSet
* @return
*/
private JFreeChart createHistogramChart(ExampleSet exampleSet) {
JFreeChart chart = ChartFactory.createHistogram(null, null, null, createHistogramDataset(exampleSet),
PlotOrientation.VERTICAL, false, false, false);
AbstractAttributeStatisticsModel.setDefaultChartFonts(chart);
chart.setBackgroundPaint(null);
chart.setBackgroundImageAlpha(0.0f);
XYPlot plot = (XYPlot) chart.getPlot();
plot.setRangeGridlinesVisible(false);
plot.setDomainGridlinesVisible(false);
plot.setOutlineVisible(false);
plot.setRangeZeroBaselineVisible(false);
plot.setDomainZeroBaselineVisible(false);
plot.setBackgroundPaint(COLOR_INVISIBLE);
plot.setBackgroundImageAlpha(0.0f);
XYBarRenderer renderer = (XYBarRenderer) plot.getRenderer();
renderer.setSeriesPaint(0, AttributeGuiTools.getColorForValueType(Ontology.NUMERICAL));
renderer.setBarPainter(new StandardXYBarPainter());
renderer.setDrawBarOutline(true);
renderer.setShadowVisible(false);
return chart;
}
@Override
public void prepareCharts() {
if (chartsArray[INDEX_HISTOGRAM_CHART] == null && getExampleSetOrNull() != null) {
chartsArray[INDEX_HISTOGRAM_CHART] = createHistogramChart(getExampleSetOrNull());
}
}
}