Java tutorial
/* * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ /* * Gamma.java * Copyright (C) 2011-2016 University of Waikato, Hamilton, New Zealand */ package adams.gui.visualization.stats.paintlet; import adams.data.spreadsheet.SpreadSheetUtils; import adams.gui.core.GUIHelper; import adams.gui.event.PaintEvent.PaintMoment; import adams.gui.visualization.core.axis.Type; import adams.gui.visualization.core.plot.Axis; import org.apache.commons.math.MathException; import org.apache.commons.math.distribution.GammaDistributionImpl; import java.awt.BasicStroke; import java.awt.Color; import java.awt.Graphics; import java.awt.Graphics2D; import java.util.Arrays; /** <!-- globalinfo-start --> * Paints the transformed gamma distribution * <br><br> <!-- globalinfo-end --> * <!-- options-start --> * Valid options are: <br><br> * * <pre>-D <int> (property: debugLevel) * The greater the number the more additional info the scheme may output to * the console (0 = off). * default: 0 * minimum: 0 * </pre> * * <pre>-stroke-thickness <float> (property: strokeThickness) * The thickness of the stroke. * default: 1.0 * minimum: 0.01 * </pre> * * <pre>-color <java.awt.Color> (property: color) * Stroke color for the paintlet * default: #000000 * </pre> * * <pre>-size <int> (property: size) * Size of the data points * default: 5 * </pre> * * <pre>-fill-point (property: fillPoint) * Whether to fill the data point with solid color * </pre> * * <pre>-fill-color <java.awt.Color> (property: fillColor) * Color for filling data point * default: #ff0000 * </pre> * * <pre>-shape <double> (property: shape) * Shape paramter for gamma distribution * default: 1.0 * </pre> * * <pre>-scale <double> (property: scale) * Scale parameter for gamma distribution * default: 1.0 * </pre> * <!-- options-end --> * * @author msf8 * @version $Revision$ */ public class Gamma extends AbstractProbabilityPaintlet { /** for serialization */ private static final long serialVersionUID = 3439914415669101587L; /**Shape parameter for the gamma distribution */ protected double m_Shape; /**Scale parameter for the gamma distribution */ protected double m_Scale; @Override protected void initialize() { super.initialize(); m_Shape = -1.0; m_Scale = -1.0; } @Override public void defineOptions() { super.defineOptions(); //shape parameter m_OptionManager.add("shape", "shape", 1.0); //scale parameter m_OptionManager.add("scale", "scale", 1.0); } /** * Set the scale parameter for the gamma distribution * @param val Scale parameter */ public void setScale(double val) { m_Scale = val; memberChanged(); } /** * Get the scale parameter for the gamma distribution * @return Scale parameter */ public double getScale() { return m_Scale; } /** * Tip text for the scale property * @return String describing the property */ public String scaleTipText() { return "Scale parameter for gamma distribution"; } /** * Set the shape parameter for the gamma distribution * @param val Shape parameter */ public void setShape(double val) { m_Shape = val; memberChanged(); } /** * Get the shape parameter for the gamma distribution * @return Shape parameter */ public double getShape() { return m_Shape; } /** * Tip text for the shape property * @return String describing the property */ public String shapeTipText() { return "Shape paramter for gamma distribution"; } @Override public void configureAxes() { m_AxisBottom = getPanel().getPlot().getAxis(Axis.BOTTOM); m_AxisLeft = getPanel().getPlot().getAxis(Axis.LEFT); m_AxisBottom.setType(Type.LOG); m_AxisBottom.setNumberFormat("#.##"); m_AxisLeft.setType(Type.LOG); m_AxisLeft.setNumberFormat("#.##"); } /** * For calculating the dimensions of the plot area. */ @Override public void calculateDimensions() { double median; GammaDistributionImpl gam = new GammaDistributionImpl(m_Shape, m_Scale); m_Sorted = SpreadSheetUtils.getNumericColumn(m_Data, m_Index); m_TransformedY = new double[m_Sorted.length]; Arrays.sort(m_Sorted); for (int i = 0; i < m_Sorted.length; i++) { median = ((i + 1) - 0.3) / (m_Sorted.length + 0.4); try { m_TransformedY[i] = gam.inverseCumulativeProbability(median); } catch (MathException e) { e.printStackTrace(); } } //If axis can handle the data if (m_AxisBottom.getType().canHandle(m_Sorted[0], m_Sorted[m_Sorted.length - 1])) { m_AxisBottom.setMinimum(m_Sorted[0]); m_AxisBottom.setMaximum(m_Sorted[m_Sorted.length - 1]); } else { getLogger().severe("errors in plotting"); } if (m_AxisLeft.getType().canHandle(m_TransformedY[0], m_TransformedY[m_TransformedY.length - 1])) { m_AxisLeft.setMinimum(m_TransformedY[0]); m_AxisLeft.setMaximum(m_TransformedY[m_TransformedY.length - 1]); } else { getLogger().severe("errors in plotting"); } m_AxisBottom.setAxisName(m_Data.getColumnName(m_Index) + ")"); m_AxisLeft.setAxisName("Inverse Gamma"); } /** * The paint routine of the paintlet. * * @param g the graphics context to use for painting * @param moment what {@link PaintMoment} is currently being painted */ @Override protected void doPerformPaint(Graphics g, PaintMoment moment) { if ((m_Data != null) && (m_Sorted != null) && m_Shape != -1.0) { GUIHelper.configureAntiAliasing(g, m_AntiAliasingEnabled); for (int i = 0; i < m_Sorted.length; i++) { Graphics2D g2d = (Graphics2D) g; //If data points are to be filled if (m_Fill) { g2d.setColor(m_FillColor); g2d.setStroke(new BasicStroke(0)); g2d.fillOval(m_AxisBottom.valueToPos(m_Sorted[i]) - m_Size / 2, m_AxisLeft.valueToPos(m_TransformedY[i]) - m_Size / 2, m_Size, m_Size); } //outline of data point g2d.setStroke(new BasicStroke(m_StrokeThickness)); g2d.setColor(m_Color); g2d.drawOval(m_AxisBottom.valueToPos(m_Sorted[i]) - m_Size / 2, m_AxisLeft.valueToPos(m_TransformedY[i]) - m_Size / 2, m_Size, m_Size); } //If drawing regression fit diagonal if (m_RegressionLine) { g.setColor(Color.BLACK); double[] newData = new double[m_Sorted.length]; for (int i = 0; i < m_Sorted.length; i++) { newData[i] = Math.log(m_Sorted[i]); } GammaDistributionImpl gd = new GammaDistributionImpl(m_Shape, m_Scale); //draw the expected diagonal line using the gamma distribution for (int i = 0; i < m_Sorted.length - 1; i++) { double p1; try { p1 = gd.cumulativeProbability(newData[i]); } catch (MathException e) { p1 = 0; } double p2; try { p2 = gd.cumulativeProbability(newData[i + 1]); } catch (MathException e) { p2 = 0; } g.drawLine(m_AxisBottom.valueToPos(m_Sorted[i]), m_AxisLeft.valueToPos(p1), m_AxisBottom.valueToPos(m_Sorted[i + 1]), m_AxisLeft.valueToPos(p2)); } } } } @Override public String globalInfo() { return "Paints the transformed gamma distribution"; } @Override public boolean hasFitLine() { return false; } }