All Downloads are FREE. Search and download functionalities are using the official Maven repository.

edu.cmu.tetradapp.editor.ScatterPlotDisplayPanel Maven / Gradle / Ivy

///////////////////////////////////////////////////////////////////////////////
// For information as to what this class does, see the Javadoc, below.       //
// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,       //
// 2007, 2008, 2009, 2010, 2014, 2015, 2022 by Peter Spirtes, Richard        //
// Scheines, Joseph Ramsey, and Clark Glymour.                               //
//                                                                           //
// 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 2 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, write to the Free Software               //
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA //
///////////////////////////////////////////////////////////////////////////////

package edu.cmu.tetradapp.editor;

import edu.cmu.tetrad.data.DataSet;
import edu.cmu.tetrad.regression.RegressionDataset;
import edu.cmu.tetrad.regression.RegressionResult;
import edu.cmu.tetrad.util.NumberFormatUtil;
import edu.cmu.tetrad.util.Parameters;

import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.awt.geom.Ellipse2D;
import java.text.NumberFormat;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * A panel that is responsible for drawing a scatter plot.
 * 

* Borrows heavily from HistogramDisplayPanel * * @author Michael Freenor */ class ScatterPlotDisplayPanel extends JPanel { /** * The line color around the histogram. */ private static final Color LINE_COLOR = Color.GRAY.darker(); /** * Variables that control the size of the drawing area. */ private int PADDINGLEFT = 75; private int PADDINGOTHER = 50; private int HEIGHT = 600 + this.PADDINGOTHER; private int WIDTH = 600 + this.PADDINGLEFT; private int SPACE = 2; /** * The default size of the component. */ private final Dimension size = new Dimension(this.WIDTH + 2 * this.SPACE, this.HEIGHT); /** * Format for continuous data. */ private final NumberFormat format = NumberFormatUtil.getInstance().getNumberFormat(); /** * The q-q plot we are displaying. */ private ScatterPlotOld scatterPlot; /** * A map from the rectangles that define the bars, to the number of units in the bar. */ private final Map rectMap = new ConcurrentHashMap<>(); /** * Constructs the scatterplot dipslay panel given the initial scatterplot to display. */ public ScatterPlotDisplayPanel(ScatterPlotOld scatterPlot) { this.scatterPlot = scatterPlot; if (scatterPlot == null) { throw new NullPointerException("Given scatter plot must be null"); } this.addMouseMotionListener(new MouseMovementListener()); this.setToolTipText(" "); } //============================ PUblic Methods =============================// /** * Updates the histogram that is dispalyed to the given one. */ public synchronized void updateScatterPlot(ScatterPlotOld scatterPlot) { if (scatterPlot == null) { throw new NullPointerException("The given scatter plot must not be null"); } this.scatterPlot = scatterPlot; this.repaint(); } public String getToolTipText(MouseEvent evt) { return null; } /** * Paints the histogram and related items. */ public void paintComponent(Graphics graphics) { double least = this.scatterPlot.getMinSample(); double greatest = this.scatterPlot.getMaxSample(); String minStr = this.format.format(least); String maxStr = this.format.format(greatest); Graphics2D g2d = (Graphics2D) graphics; FontMetrics fontMetrics = g2d.getFontMetrics(); int widthMinStr = fontMetrics.stringWidth(minStr); int widthMaxStr = fontMetrics.stringWidth(maxStr); this.PADDINGLEFT = Math.max(widthMinStr, widthMaxStr); this.PADDINGOTHER = 50; this.HEIGHT = 600 + this.PADDINGOTHER; this.WIDTH = 600 + this.PADDINGLEFT; this.SPACE = 2; int DASH = 10; setSize(new Dimension(this.WIDTH + 2 * this.SPACE, this.HEIGHT)); // set up variables. this.rectMap.clear(); int height = this.HEIGHT - this.PADDINGOTHER; // draw background/surrounding box. g2d.setColor(this.getBackground()); g2d.fillRect(0, 0, this.WIDTH + 2 * this.SPACE, this.HEIGHT); g2d.setColor(Color.WHITE); g2d.fillRect(this.PADDINGLEFT, 0, (this.WIDTH + this.SPACE) - this.PADDINGLEFT, height); //border g2d.setColor(ScatterPlotDisplayPanel.LINE_COLOR); g2d.drawRect(this.PADDINGLEFT, 0, (this.WIDTH + this.SPACE) - this.PADDINGLEFT, height - 2 * this.SPACE); // draw the buttom line g2d.setColor(ScatterPlotDisplayPanel.LINE_COLOR); g2d.drawString(minStr, this.PADDINGLEFT + 5, height + 15); g2d.drawLine(this.PADDINGLEFT, height + DASH, this.PADDINGOTHER, height); g2d.drawString(maxStr, this.WIDTH - widthMaxStr, height + 15); g2d.drawLine(this.WIDTH + this.SPACE, height + DASH, this.WIDTH + this.SPACE, height); // draw the side line g2d.setColor(ScatterPlotDisplayPanel.LINE_COLOR); final int topY = 0; g2d.drawString(maxStr, this.PADDINGLEFT - fontMetrics.stringWidth(maxStr), topY + 10); g2d.drawLine(this.PADDINGLEFT - DASH, topY, this.PADDINGOTHER, topY); g2d.drawString(minStr, this.PADDINGLEFT - fontMetrics.stringWidth(minStr), height - 2); g2d.drawLine(this.PADDINGLEFT - DASH, height, this.PADDINGOTHER, height); //draw the origin lines if they should go on the screen -- first find out where they exist if (this.scatterPlot.getMinSample() < 0 && this.scatterPlot.getMaxSample() > 0) { double[] originLeft = plotPoint(least, 0, least, greatest); double[] originRight = plotPoint(greatest, 0, least, greatest); double[] originTop = plotPoint(0, least, least, greatest); double[] originBottom = plotPoint(0, greatest, least, greatest); g2d.drawLine((int) originLeft[0] + 2, (int) originLeft[1] + 2, (int) originRight[0] + 2, (int) originRight[1] + 2); g2d.drawLine((int) originTop[0] + 2, (int) originTop[1] + 2, (int) originBottom[0] + 2, (int) originBottom[1] + 2); } g2d.setColor(new Color(255, 0, 0)); //draw each point in the indexSet from our ScatterPlot for (Object o : this.scatterPlot.getIndexSet()) { int i = (Integer) o; double x = this.scatterPlot.getxData()[i]; double y = this.scatterPlot.getyData()[i]; double[] result = plotPoint(x, y, least, greatest); g2d.fill(new Ellipse2D.Double(result[0], result[1], 4, 4)); } //draw the regression line if (this.scatterPlot.isDrawRegLine()) { //RegressionRunner regRunner; RegressionDataset regData; /* * In the following code, the complement of the indexSet (for all integers <= (n - 1)) is * calculated. This set of indices is removed from a copy of our original dataSet, such * that the ScatterPlot only contains the appropriate points for rendering. */ Parameters params = new Parameters(); params.set("targetName", this.scatterPlot.getYVariable().getName()); if (this.scatterPlot.getIndexSet().size() != this.scatterPlot.getDataSet().getNumRows()) { DataSet newDataSet = this.scatterPlot.getDataSet().copy(); int[] throwAway = new int[this.scatterPlot.getComplementIndexSet().size()]; for (int j = 0; j < throwAway.length; j++) { throwAway[j] = (Integer) this.scatterPlot.getComplementIndexSet().get(j); } newDataSet.removeRows(throwAway); regData = new RegressionDataset(newDataSet); //regRunner = new RegressionRunner(new DataWrapper(newDataSet), params); } else { regData = new RegressionDataset(this.scatterPlot.getDataSet()); //regRunner = new RegressionRunner(new DataWrapper(scatterPlot.dataSet), params); } //regRunner.execute(); RegressionResult regResult = regData.regress(this.scatterPlot.getYVariable(), this.scatterPlot.getXVariable()); double[] coef = regResult.getCoef(); double[] regLeft = plotPoint(least, coef[0] + coef[1] * least, least, greatest); double[] regRight = plotPoint(greatest, coef[0] + coef[1] * greatest, least, greatest); g2d.setColor(ScatterPlotDisplayPanel.LINE_COLOR); g2d.drawLine((int) regLeft[0] + 2, (int) regLeft[1] + 2, (int) regRight[0] + 2, (int) regRight[1] + 2); } // draw the display string. g2d.setColor(ScatterPlotDisplayPanel.LINE_COLOR); } /** * @param x Location along the X axis. * @param y Location along the Y axis (Cartesian coordinates, not Java2D). * @param minRange The value at the origin. * @param maxRange The value at the extremity (determined by the largest value encountered in either variable). * @return An ordered pair determining the proper location on the screen in Java2D coordinates. */ private double[] plotPoint(double x, double y, double minRange, double maxRange) { double[] result = new double[2]; double range = maxRange - minRange; result[0] = (this.WIDTH - this.PADDINGLEFT) * ((x - minRange) / range) + 4 + this.PADDINGLEFT; result[1] = this.HEIGHT - (this.HEIGHT - this.PADDINGOTHER) * ((y - minRange) / range) - 8 - this.PADDINGOTHER; return result; } public Dimension getPreferredSize() { return this.size; } public Dimension getMaximumSize() { return this.size; } public Dimension getMinimumSize() { return this.size; } //============================ Inner class =====================================// private class MouseMovementListener implements MouseMotionListener { public void mouseDragged(MouseEvent e) { } public void mouseMoved(MouseEvent e) { Point point = e.getPoint(); for (Rectangle rect : ScatterPlotDisplayPanel.this.rectMap.keySet()) { if (rect.contains(point)) { break; } } } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy