Package statechum.analysis.learning

Source Code of statechum.analysis.learning.DrawGraphs$RBoxPlot

/* Copyright (c) 2011 Neil Walkinshaw and Kirill Bogdanov
*
* This file is part of StateChum.
*
* StateChum 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.
*
* StateChum 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 StateChum.  If not, see <http://www.gnu.org/licenses/>.
*/

/*
* Installation of RJava, JavaGD and aplpack on Debian x86_64:
* apt-get install r-base
*
* (note: an alternative way to install javagd is from http://blog.binfalse.de/2011/02/talking-r-through-java/
*  which boils down to apt-get install r-cran-rjava
* Asking R to install packages itself will fail on a PAX-enabled system because binaries it generates does not have
* mprotect disabled, to make this work you have to change every line in the two configure files of rJava which
* says
* ac_try='./conftest$ac_exeext'
* to read
* ac_try='paxctl -Cm ./conftest$ac_exeext;./conftest$ac_exeext'
* After that, configure will be successful. The outcome can be turned back into rJava.tar.gz and R will install it via
* install.packages("/tmp/RtmpxtSS7S/downloaded_packages/rJava-modified.tar.gz")
* As root:
*
* R CMD javareconf
*
* (it uses getsp.java also available in JavaGD distribution (getsp.java takes java.library.path and splits it into segments prefixed by -L ,
* on Debian it is stored in /usr/share/R/share/java/getsp.class )
* Note that R CMD config CC obtains C compiler for R, similar for other flags.
*
* Then unpack JavaGD into /usr/local/src/JavaGD and then run
*
* R CMD INSTALL JavaGD
*
* from /usr/local/src, this builds and installs the package.
*
* In a similar way, I can install rJava, but perhaps it is prudent to disable extra package loading via JRIBootstrap.java
*
* During installation packages are placed in /usr/local/lib/R/site-library and I have to include /usr/local/lib/R/site-library/rJava/jri/ in java.library.path
* In addition, R_HOME has to be set to /usr/lib/R (in Eclipse Run configuration).
*
* In order to use bagplots, the following is needed,
* R CMD INSTALL aplpack
*
* Installation of the above on MacOSX and Win32:
*
* install.packages(c("JavaGD","rJava","aplpack"))
* On MacOS, tcltk is a special download which installs into /usr/local.
*
* Where R is install from Macports, I need to installed both as follows:
* <pre>
* port install tk +x11
* port install R +gfortran48 +x11 +tcltk
* </pre>
* Installing a pre-built binary from R web site does not work because it is linked to Quartz that appears to be missing, most likely because they have used Lion or something similar).
*
* R_HOME needs to be set to /opt/local/Library/Frameworks/R.framework/Resources
* and /opt/local/Library/Frameworks/R.framework/Versions/3.0/Resources/library/rJava/jri needs adding to java.library.path
*
*/


// This file is based on rtest.java

package statechum.analysis.learning;
import java.awt.geom.Rectangle2D;
import java.io.BufferedReader;
import java.io.File;
import java.io.InputStreamReader;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.TreeMap;

import javax.swing.SwingUtilities;

import org.rosuda.JRI.REXP;
import org.rosuda.JRI.RMainLoopCallbacks;
import org.rosuda.JRI.Rengine;

import statechum.Configuration;
import statechum.GlobalConfiguration;
import statechum.GlobalConfiguration.G_PROPERTIES;
import statechum.Helper;

public class DrawGraphs {
  /** Determines whether our callbacks are dummies (without a main loop) or active (main loop running).
   */
  static boolean mainLoopRunning = false;
 
  public static class ConsoleCallbacks implements RMainLoopCallbacks
  {

    @SuppressWarnings("unused")
    @Override
    public void rBusy(Rengine arg0, int arg1) {
      // dummy
    }

    @SuppressWarnings("unused")
    @Override
    public String rChooseFile(Rengine arg0, int arg1) {
      // dummy
      return null;
    }

    @SuppressWarnings("unused")
    @Override
    public void rFlushConsole(Rengine arg0) {
      // dummy
    }

    @SuppressWarnings("unused")
    @Override
    public void rLoadHistory(Rengine arg0, String arg1) {
      // dummy
    }

        private BufferedReader br=new BufferedReader(new InputStreamReader(System.in));

        /** Mostly from rtest.java */
        @SuppressWarnings("unused")
    @Override
    public String rReadConsole(Rengine arg0, String prompt, int arg2) {
          if (!mainLoopRunning) return null;
         
         System.out.print(prompt);
          try {
              String s=br.readLine();
              return (s==null||s.length()==0)?s:s+"\n";
          } catch (Exception e) {
              System.out.println("rReadConsole exception: "+e.getMessage());
          }
          return null;
    }

    @SuppressWarnings("unused")
    @Override
    public void rSaveHistory(Rengine arg0, String arg1) {
      // dummy
    }

    @SuppressWarnings("unused")
    @Override
    public void rShowMessage(Rengine arg0, String arg1) {
      if (mainLoopRunning) System.out.println(arg1);
    }

    @SuppressWarnings("unused")
    @Override
    public void rWriteConsole(Rengine arg0, String arg1, int arg2) {
      if (mainLoopRunning) System.out.println(arg1);
      else
      {
        consoleBuffer.append(arg1);consoleBuffer.append('\n');
      }
    }
   
    private StringBuffer consoleBuffer = new StringBuffer();
   
    public void clearBuffer()
    {
      consoleBuffer = new StringBuffer();
    }
   
    public String getBuffer()
    {
      return consoleBuffer.toString();
    }
  }
 
  /** R engine - can only be initalised once - second time packages do not load ("setwd(x) cannot change directory")
   * because F:/R/windows64/R-2.12.2/library is passed to setwd and even if the correct value is passed, package
   * loading fails.
   */
  protected static Rengine engine;
  protected static ConsoleCallbacks callbacks = new ConsoleCallbacks();
 
  public DrawGraphs()
  {
    java.lang.reflect.Method loadJri = null;
     
    try
    {
      loadJri = Rengine.class.getMethod("loadJri", new Class[]{String.class});
    } catch (Exception e)
    {// ignore this, loadJri remains null.
    }
   
    try
    {
      if (loadJri != null && !((Boolean)loadJri.invoke(null, GlobalConfiguration.getConfiguration().getProperty(G_PROPERTIES.PATH_JRILIB))).booleanValue())
        throw new IllegalArgumentException("JRI library could not be loaded");
    } catch (IllegalAccessException e)
    {
      throw new IllegalArgumentException("Calling a method to load JRI library failed",e);
    } catch (InvocationTargetException e)
    {
      throw new IllegalArgumentException("Calling a method to load JRI library failed",e);
    } // IllegalArgumentException thrown by the above should propagate

    if (!Rengine.versionCheck())
      throw new IllegalArgumentException("R version mismatch");
    if (engine == null)
    {
      engine = new Rengine(new String[]{"--vanilla"},false,callbacks);
      //engine.setDaemon(true);
      if (!engine.waitForR())
        throw new IllegalArgumentException("loading R failed");

      Runtime.getRuntime().addShutdownHook(new Thread() {
          @Override
        public void run() {
            end();
          }
      });
      eval("library(aplpack)","loading BagPlot");

      // detect if compression is supported
      pdfCompression = eval("is.element(\"compress\",names(formals(pdf)))","failed to detect whether compression is supported").asBool().isTRUE();
    }
  }

  protected static REXP eval(String whatToEval, String errMsg)
  {
    callbacks.clearBuffer();
    REXP result = engine.eval(whatToEval);
    if (result == null)
      throw new IllegalArgumentException(errMsg+" : "+callbacks.getBuffer());
    return result;
  }

  protected static <ELEM> String vectorToR(List<ELEM> vector, boolean addQuotes)
  {
    if (vector.size() == 0) throw new IllegalArgumentException("cannot plot an empty graph");
    StringBuffer result = new StringBuffer();
    result.append("c(");
    boolean startVector = true;
    for(ELEM elem:vector)
    {
      if (!startVector) result.append(",");else startVector=false;
      if (addQuotes)   result.append('\"');
      result.append(elem);
      if (addQuotes)   result.append('\"');
    }
    result.append(")");
    return result.toString();
  }
 
  public static final String defaultColour = "green";
 
  /**
   * Formats a box plotting command to R.
   *
   * @param data what to plot
   * @param names names of boxes
   * @param colour colour of boxes
   * @param otherAttrs additional attributes to set, null if not used.
   * @return The string to be sent to R for evaluation.
   */
  protected static String boxPlotToString(List<List<Double>> data,List<String> names,List<String> colour, String otherAttrs)
  {
    if (data.size() == 0) throw new IllegalArgumentException("cannot plot an empty graph");
    if (data.size() == 1 && names != null) throw new IllegalArgumentException("in a graph with one component, names are not used");
    if (data.size() > 1 && names != null && names.size() != data.size()) throw new IllegalArgumentException("mismatch between name and data length");
    StringBuffer result = new StringBuffer();
    result.append("boxplot(");
    boolean firstVectorOfData = true;
    for(List<Double> arg:data)
    {
      if (!firstVectorOfData) result.append(",");else firstVectorOfData=false;
      result.append(vectorToR(arg,false));
    }
   
    // names
    if (names != null)
    {
      result.append(",names=");
      result.append(vectorToR(names, true));
    }
   
    // colours
    {
      result.append(",col=");
      if (colour != null) result.append(vectorToR(colour,true));
      else
      {// no colours provided, using the default one
        boolean startVector = true;
        result.append("c(");
        for(int i=0;i<data.size();++i)
        {
          if (!startVector) result.append(",");else startVector=false;
          result.append('\"');
          String col = defaultColour;
          result.append(col);
          result.append('\"');
        }
        result.append(")");
      }
    }
    if (otherAttrs != null) { result.append(',');result.append(otherAttrs); }
    result.append(")");
    return result.toString();
  }
 
  /**
   * Formats a bag plotting command to R.
   *
   * @param yData what to plot vertically
   * @param xData what to plot horizontally
   * @param otherAttrs additional attributes to set, null if not used.
   * @return The string to be sent to R for evaluation.
   */
  protected static String datasetToString(String plotType,List<List<Double>> yData,List<Double> xData, String otherAttrs)
  {
    if (yData.size() == 0) throw new IllegalArgumentException("cannot plot an empty graph");
    if (yData.size() != xData.size()) throw new IllegalArgumentException("mismatch between x and y length");
    StringBuffer result = new StringBuffer();
    result.append(plotType);result.append("(");
    StringBuffer yAxisData = new StringBuffer();
    Iterator<Double> xArgIterator = xData.iterator();
    result.append("c(");yAxisData.append(",c(");
    boolean startVector = true;
    for(List<Double> yArg:yData)
    {
      Double xArg = xArgIterator.next();
      for(Double elem:yArg)
      {
        if (!startVector) { yAxisData.append(",");result.append(','); } else startVector=false;
        yAxisData.append(elem);result.append(xArg);
      }
    }
    result.append(')');yAxisData.append(')');
    result.append(yAxisData);

    if (otherAttrs != null && !otherAttrs.isEmpty()) { result.append(',');result.append(otherAttrs); }
    result.append(")");
    return result.toString();
  }
 
  private static boolean javaGDLoaded = false;
 
  /** Newer versions of R permit pdf compression, but older ones choke if I attempt to use it.
   */
  private static boolean pdfCompression = false;
 
  /** Since I cannot pass arguments to RViewer during it construction, static values have to be set and
   * then copied into the new object. For this reason, creation of graphs has to be serialised, this is done
   * by running it all on the Swing thread (avoids a deadlock associated with resizing of the window
   * and us doing something to it at the same time on different threads).
   */
  public void drawInteractivePlot(final List<String> dataToPlot,final String title)
  {
    // First, load javaGD
    if (!javaGDLoaded)
    {
      // based on http://www.algorithm-forge.com/techblog/2010/07/using-javagd-in-java-applications/
      engine.eval(".setenv <- if (exists(\"Sys.setenv\")) Sys.setenv else Sys.putenv");
      engine.eval(".setenv(\"JAVAGD_CLASS_NAME\"=\"statechum/analysis/learning/RViewer\")");
      eval("library(JavaGD)","loading JavaGD");
     
      javaGDLoaded = true;
    }

    try {
      SwingUtilities.invokeAndWait(new Runnable() {
        @Override
        public void run()
        {
          if (RViewer.getGraph(title) == null)
          {// create new graph
            RViewer.setNewGraphName(title);
            eval("JavaGD(\"aa\")","JavaGD() failed");
            REXP devNum = eval("dev.cur()","failed to do dev.cur");
           
            RViewer.getGraph(title).init(devNum.asInt()-1);
          }
          eval("dev.set("+(RViewer.getGraph(title).getDeviceNumber()+1)+")","failed to do dev.set for "+title);
          for(String cmd:dataToPlot)
            eval(cmd,"failed to run plot "+cmd);
        }
      });
    } catch (Exception e) {
      Helper.throwUnchecked("could not draw graph "+title, e);
    }
  }


  /** Draws a plot given the data to plot and stores it in the given file.
   *
   * @param drawingCommand drawing command to pass to R
   * @param xDim horizontal size in inches, R default is 7.
   * @param yDim vertical size in inches, R default is 7.
   * @param fileName where to store result.
   */
  public void drawPlot(List<String> drawingCommand,double xDim,double yDim,File file)
  {
    if (xDim < 1)
      throw new IllegalArgumentException("horizontal size ("+xDim+") too small");
    if (yDim < 1) throw new IllegalArgumentException("vertical size ("+yDim+") too small");
   
    if (file.exists() && file.delete() == false)
      throw new IllegalArgumentException("cannot delete file "+file.getAbsolutePath());
    // Slashes have to be the Unix-way - R simply terminates the DLL on WinXP otherwise.
    String fullName = file.getAbsolutePath().replace(File.separatorChar, '/');
    eval("pdf(\""+fullName+"\","+xDim+","+yDim
        +(pdfCompression?",compress=FALSE":"") // disable pdf compression if enabled
        +")","redirection to pdf("+file.getAbsolutePath()+") failed");
    for(String cmd:drawingCommand)
      eval(cmd,"failed to run "+cmd);
    eval("dev.off()","failed to write to "+file.getAbsolutePath());
  }

  /**
   * Shuts down jri thread - since jri is not a daemon thread JVM will not exit if this is not called.
   */
  public static void end()
  {
    if (engine != null)
    {
      for(RViewer v:RViewer.nameToGraph.values())  v.gdClose();
      engine.end();
      engine=null
    }   
  }

  public static class DataColumn
  {
    /** Data to be displayed. */
    final List<Double> results;
    /** Colour to use, if {@code null} default colour is used. */
    String colour;
    /** Label to be used, if {@code null} column identifier is used. */
    String label;
   
    public DataColumn()
    {
      results = new ArrayList<Double>(1000);
    }
  }
 
  /**
   * Represents a graph.
   *
   * @param <ELEM> type of elements for the X axis, vertical is always a Double
   */
  public static abstract class RGraph<ELEM extends Comparable<? super ELEM>>
  {
    Map<ELEM,DataColumn> collectionOfResults = new TreeMap<ELEM,DataColumn>();
   
    protected final String xAxis,yAxis;
    protected final File file;
   
    /** Number of entries in the graph. */
    protected int size = 0;
   
    /** Additional drawing command to append to a plot, such as abline() command. */
    protected List<String> extraCommands = new LinkedList<String>();
   
    public void addExtraCommand(String cmd)
    {
      extraCommands.add(cmd);
    }
   
    public RGraph(String x,String y,File name)
    {
      xAxis=x;yAxis=y;file=name;
    }
   
    protected ELEM xMin = null, xMax = null;
    protected Double yMin = null, yMax = null;
   
    public void setXboundaries(ELEM min, ELEM max)
    {
      xMin = min;xMax = max;
    }
   
    public void setYboundaries(double min, double max)
    {
      yMin = min;yMax = max;
    }
   
    public synchronized void add(ELEM el,Double value)
    {
      if (yMin != null && yMin.doubleValue() > value.doubleValue()) return;
      if (yMax != null && yMax.doubleValue() < value.doubleValue()) return;
     
      if (xMin != null && xMin.compareTo(el) > 0) return;
      if (xMax != null && xMax.compareTo(el) < 0) return;
     
      DataColumn column = collectionOfResults.get(el);
      if (column == null) { column=new DataColumn();collectionOfResults.put(el,column); }
      column.results.add(value);
      ++size;
    }
   
    public synchronized void add(ELEM el,Double value, String colour)
    {
      add(el,value);collectionOfResults.get(el).colour=colour;
    }
   
    public int size()
    {
      return size;
    }
   
    /** Same as {@link add} but additionally permits setting of both colour and a label for this
     * column of data values.
     * @param el identifier for the column
     * @param value value to be added to it
     * @param colour colour with which box plot values are to be shown
     * @param label label to show on the horizonal axis, empty string for no label.
     */
    public synchronized void add(ELEM el,Double value, String colour, String label)
    {
      add(el,value);
      if (colour != null) collectionOfResults.get(el).colour=colour;
      if (label != null) collectionOfResults.get(el).label=label;
    }
   
    /** Returns a command to draw a graph in R. */
    protected abstract List<String> getDrawingCommand();
   
    public void drawInteractive(DrawGraphs gr)
    {
      List<String> drawingCommands = new LinkedList<String>();
      drawingCommands.addAll(getDrawingCommand());drawingCommands.addAll(extraCommands);
      gr.drawInteractivePlot(drawingCommands, file.getName());
    }
   
    protected double xSize = -1;
   
    /** Sets the horizonal size of the plot, vertical size is always set to 4 inches.
     * If no assignemnt is made, the size is guessed from the number of points on the drawing.
     */
    public void setXSize(double newSize)
    {
      xSize = newSize;
    }
   
    double ySize = 4;

    public void drawPdf(DrawGraphs gr)
    {
      if (collectionOfResults.size() > 0)
      {
        double horizSize = xSize;
        if (horizSize <= 0) horizSize=computeHorizSize();
        List<String> drawingCommands = new LinkedList<String>();
        drawingCommands.addAll(getDrawingCommand());drawingCommands.addAll(extraCommands);
        gr.drawPlot(drawingCommands, horizSize,ySize,file);
      }
      else
        if (GlobalConfiguration.getConfiguration().isAssertEnabled())
          System.out.println("WARNING: ignoring empty plot that was supposed to be written into "+file);
    }
   
    /* Computes the horizontal size of the drawing. */
    abstract protected double computeHorizSize();
   
    /** Reports the name of the file with the graph, used for identification of different graphs. */
    public String getFileName()
    {
      return file.getName();
    }
  }
 
  public static class RBoxPlot<ELEM extends Comparable<? super ELEM>> extends RGraph<ELEM>
  {
    public RBoxPlot(String x, String y, File name) {
      super(x, y, name);
    }
   
    @Override
    public List<String> getDrawingCommand()
    {
      List<List<Double>> data = new LinkedList<List<Double>>();
      List<String> names = new LinkedList<String>(), colours = new LinkedList<String>();
      for(Entry<ELEM,DataColumn> entry:collectionOfResults.entrySet())
      {
        data.add(entry.getValue().results);
        String label = entry.getValue().label;
        if (label == null)
          label = entry.getKey().toString();
        names.add(label);
        String colour = entry.getValue().colour;
        if (colour == null) colour = defaultColour;
        colours.add(colour);
      }
      return Collections.singletonList(boxPlotToString(data, names.size()==1?null:names,colours,
          (!xAxis.isEmpty() || !yAxis.isEmpty())"xlab=\""+xAxis+"\",ylab=\""+yAxis+"\""
          :null   
          ));
    }

    @Override
    protected double computeHorizSize() {
      double horizSize=ySize*collectionOfResults.keySet().size()/5;if (horizSize < ySize) horizSize = ySize;
      return horizSize;
    }
  }
 
  public static class RBoxPlotP<ELEM extends Comparable<? super ELEM>> extends RGraph<ELEM>
  {
    public RBoxPlotP(String x, String y, File name) {
      super(x, y, name);
    }
   
    @Override
    public List<String> getDrawingCommand()
    {
      List<List<Double>> data = new LinkedList<List<Double>>();
      List<String> names = new LinkedList<String>(), colours = new LinkedList<String>();
      for(Entry<ELEM,DataColumn> entry:collectionOfResults.entrySet())
      {
        data.add(entry.getValue().results);
        String label = entry.getValue().label;
        if (label == null)
          label = entry.getKey().toString();
        names.add(label);
        String colour = entry.getValue().colour;
        if (colour == null) colour = defaultColour;
        colours.add(colour);
      }
      return Collections.singletonList(boxPlotToString(data, names.size()==1?null:names,colours,"xlab=\""+xAxis+"\",ylab=\""+yAxis+"\",las=2"));
    }

    @Override
    protected double computeHorizSize() {
      double horizSize=ySize*collectionOfResults.keySet().size()/5;if (horizSize < ySize) horizSize = ySize;
      return horizSize;
    }
  }
  public static class RBagPlot extends Graph2D
  {
    public RBagPlot(String x, String y, File name) {
      super(x, y,"bagplot", name);
    }
    /** Returns a string reflecting the number of points R bagplot analysis will be limited to. */
    protected String formatApproxLimit()
    {
      return (limit == null?"":"approx.limit="+limit.intValue());
    }
    protected Integer limit = null;

    /** By default, R's bagplot limits the number of points for analysis to 300, this one makes it possible to change that value. */
    public void setLimit(int value)
    {
      limit = value;
    }
   
    @Override
    public String otherOptions()
    {
      return formatApproxLimit();
    }
  }
  public static class Graph2D extends RGraph<Double>
  {
    public Graph2D(String x, String y, String plotKind, File name) {
      super(x, y, name);plotType=plotKind;
    }
    List<List<Double>> data = null;
    List<Double> names = null;
   
    public void computeDataSet()
    {
      data = new LinkedList<List<Double>>();
      names = new LinkedList<Double>();
      for(Entry<Double,DataColumn> entry:collectionOfResults.entrySet())
      {
        data.add(entry.getValue().results);names.add(entry.getKey());
      }
    }
       
    final protected String plotType;
   
    public String otherOptions()
    {
      return "";
    }
   
    @Override
    public List<String> getDrawingCommand()
    {
      computeDataSet();
      return Collections.singletonList(datasetToString(plotType,data, names,"xlab=\""+xAxis+"\",ylab=\""+yAxis+"\""+
          otherOptions()));
    }
   
    public boolean graphOk()
    {
      Rectangle2D.Double graphSize = getSize();
      if (graphSize.width < Configuration.fpAccuracy)
        return false;
      if (graphSize.height < Configuration.fpAccuracy)
        return false;
   
      return true;
    }
   
    /** Computes the data for abline to draw a diagonal. */
    public String computeDiagonal()
    {
      Rectangle2D.Double graphSize = getSize();
      if (graphSize.width < Configuration.fpAccuracy)
        throw new IllegalArgumentException("width is too small");
      if (graphSize.height < Configuration.fpAccuracy)
        throw new IllegalArgumentException("height is too small");
     
      double k = graphSize.height/graphSize.width;
      double diff = graphSize.y-k*graphSize.x;
     
      return "abline("+diff+","+k+")";
    }
   
    public Rectangle2D.Double getSize()
    {
      Double xValueMin = null, xValueMax = null, yValueMin = null, yValueMax = null;
      // if there is nothing useful to draw, do not pass the command to Bagplot - it will crash (as of May 24, 2011).
      Iterator<Entry<Double,DataColumn>> resultIterator = collectionOfResults.entrySet().iterator();

      while(resultIterator.hasNext())
      {
        Entry<Double,DataColumn> entry = resultIterator.next();
        if (xValueMin == null) { xValueMin = entry.getKey();xValueMax = entry.getKey(); }
        if (xValueMin.compareTo(entry.getKey()) > 0) xValueMin = entry.getKey();
        if (xValueMax.compareTo(entry.getKey()) < 0) xValueMax = entry.getKey();
       
        for(Double y:entry.getValue().results)
        {
          if (yValueMin == null) { yValueMin = y;yValueMax = y; }
          if (yValueMin.compareTo(y) > 0) yValueMin = y;
          if (yValueMax.compareTo(y) < 0) yValueMax = y;
        }
      }
     
      if (xValueMin == null || yValueMin == null)
        return new Rectangle2D.Double();
     
      return new Rectangle2D.Double(xValueMin,yValueMin,xValueMax-xValueMin,yValueMax-yValueMin);
    }
   
    @Override
    public void drawInteractive(DrawGraphs gr)
    {
      if (!checkSingleDot())
        super.drawInteractive(gr);
      else
        if (GlobalConfiguration.getConfiguration().isAssertEnabled())
          System.out.println("WARNING: not popping bagplot "+file+" consisting of a single dot due to R bug");
    }
   
    @Override
    protected double computeHorizSize() {
      return ySize;
    }

    public boolean checkSingleDot() {
      return getSize().width < Configuration.fpAccuracy && getSize().height < Configuration.fpAccuracy;
    }
  }
 
  public static class ScatterPlot extends Graph2D
  {

    public ScatterPlot(String x, String y, File name) {
      super(x, y, "plot", name);
    }
   
  }
 
  /** Draws a square bag plot. */
  public static class SquareBagPlot extends RBagPlot
  {
    protected final boolean diag;
    protected final double minValue, maxValue;
    /**
     *
     * @param x name of the X axis
     * @param y name of the Y axis
     * @param name file where to store .pdf (should include the extension).
     * @param from the minimal value of x or y.
     * @param to the maximal value of x or y.
     * @param diagonal whether to draw a diagonal line
     */
    public SquareBagPlot(String x, String y, File name, double from, double to, boolean diagonal) {
      super(x, y, name);diag = diagonal;minValue = from;maxValue = to;
    }
   
    @Override
    public List<String> getDrawingCommand()
    {
      computeDataSet();
      List<String> result = new LinkedList<String>();
      result.add("bplot<-compute."+datasetToString(plotType,data, names,formatApproxLimit()));
      result.add("plot(bplot,xlim=c("+minValue+","+maxValue+"), ylim=c("+minValue+","+maxValue+"),xlab=\""+xAxis+"\",ylab=\""+yAxis+"\")");
      if (diag) result.add("abline(0,1)");
      return result;
    }
  }
}

TOP

Related Classes of statechum.analysis.learning.DrawGraphs$RBoxPlot

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.