Java source code of 'jhplot.PND'

/**
*    Copyright (C)  DataMelt project. The jHPLot package by S.Chekanov and Work.ORG
*    All rights reserved.
*
*    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 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 .
*
*    Additional permission under GNU GPL version 3 section 7:
*    If you have received this program as a library with written permission from the DataMelt team,
*    you can link or combine this library with your non-GPL project to convey the resulting work.
*    In this case, this library should be considered as released under the terms of
*    GNU Lesser public license (see ),
*    provided you include this license notice and a URL through which recipients can access the
*    Corresponding Source.
**/
package jhplot;

import hep.aida.IAnalysisFactory;
import hep.aida.IDataPointSet;
import hep.aida.IDataPointSetFactory;
import hep.aida.ITree;
import java.io.*;
import java.net.URL;
import java.util.ArrayList;
import java.util.StringTokenizer;
import java.util.Date;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import jhplot.stat.Statistics;
import jhplot.gui.HelpBrowser;
import jhplot.io.PReader;
import jhplot.math.DoubleArray;

/**
 * Data holder in 2D for double values. It is similar  to a matrix in 2D. 
 * It has columns and rows. The number of columns
 * may not be the same. For example, data can be presented as: 

*

 * 1 2 3 4 5
 * 12 3 4
 * 1 3 4 555 5 66 77
 * 1 2 2 33 434 4
 * 
*

* All numbers are expected to be in double precision.

* It extends ArrayList and adds many new * features for data manipulation. The class does not have graphical option (use * H1D to show the data or methods of this class which transform P0D to a H1D * histogram). * * @author S.Chekanov * */ public class PND implements Serializable { /** * */ private static final long serialVersionUID = 1L; private ArrayList data; private String title; private int dimension; private double min = 0; private double max = 0; /** * Construct an empty container with a title * * @param title * A title * */ public PND(String title) { data = new ArrayList(); this.title = title; this.dimension = 0; } /** * Construct a copy from a PND. If the last argument is true, a shallow copy * of a collection. In this case a new collection contains references to * same objects as the source collection. Data are not cloned * * @param title * new title * @param shallow * if true, a shallow copy of a collection. * @param pnd * inpit data */ public PND(String title, boolean shallow, PND pnd) { this.title = title; this.data = new ArrayList(); this.dimension = pnd.getDimension(); if (shallow) { // ArrayList jplot3d=p0d.getArrayList(); data = (ArrayList) (pnd.getArrayList().clone()); } else { for (int i = 0; i < pnd.size(); i++) data.add(pnd.get(i)); } } /** * Construct a container with a title from external file (see the method * toFile() how to write such ASCII file). * * @param title * A title * * @param file * input file name. It can be either a file on a file system or * URL location (must start from http or ftp) */ public PND(String title, String file) { this.dimension = 0; data = new ArrayList(); this.title = title; read(file); } /** * Construct an empty container with no title * */ public PND() { this("NOT SET"); } /** * Set a new title * * @param title * New Title */ public void setTitle(String title) { this.title = title; } /** * Set a new title * * @param title * New Title */ public void setName(String title) { this.title = title; } /** * Get a new title. * * @return Title */ public String getTitle() { return this.title; } /** * Get a new title * * @return Title */ public String getName() { return this.title; } /** * Clear the container */ public void clear() { data.clear(); } /** * Return a specific row as array * * @param row * index of the row * * @return array of values */ public double[] get(int row) { return (double[]) data.get(row); } /** * Return a specific row as P0D * * @param row * index of the row * * @return array of values */ public P0D getRowP0D(int row) { P0D p = new P0D(title + ":row:" + Integer.toString(row)); p.fill((double[]) data.get(row)); return p; } /** * Return a specific value. * * @param row * row index * @param column * column index * * @return value */ public double get(int row, int column) { double[] tmp = (double[]) data.get(row); return tmp[column]; } /** * Get a string representing PND * * * @return String with all values */ public String toString() { String tmp = "\nPND: " + title + "\n"; for (int i = 0; i < data.size(); i++) { double[] tt = (double[]) data.get(i); for (int j = 0; j < tt.length; j++) { tmp += Double.toString(tt[j]); tmp += " "; } tmp += "\n"; } return tmp; } /** * Print PND to System.out. */ public void print() { System.out.println(this.toString()); } /** * Return a specific column as an array * * @param column * index of the column * * @return P0D array with values. * */ public P0D getP0D(int column) { P0D tmp = new P0D(title + " :" + Integer.toString(column)); if (column >= dimension) { ErrorMessage("Index is too large"); return tmp; } for (int j = 0; j < data.size(); j++) { double[] tt = (double[]) data.get(j); tmp.add(tt[column]); } return tmp; } /** * Return a specific column as an array * * @param column * index of the column * * @return array with values. * */ public double[] getColumn(int column) { double[] tmp = new double[data.size()]; if (column >= dimension) { ErrorMessage("Index is too large"); return tmp; } for (int j = 0; j < data.size(); j++) { double[] tt = (double[]) data.get(j); tmp[j] = tt[column]; } return tmp; } /** * Return a specific column as P0D object * * @param column * index of the column * * @return array with values. * */ public P0D getColumnP0D(int column) { P0D tmp = new P0D("Column:" + Integer.toString(column)); if (column >= dimension) { ErrorMessage("Index is too large"); return tmp; } for (int j = 0; j < data.size(); j++) { double[] tt = (double[]) data.get(j); tmp.add(tt[column]); } return tmp; } /** * Return 2 columns as P1D to show as a X-Y plot * * @param c1 * index of the first column * @param c2 * index of the second column * * @return P1D array with X-Y values. * */ public P1D getP1D(int c1, int c2) { P1D tmp = new P1D(title + ":" + Integer.toString(c1) + "-" + Integer.toString(c2)); tmp.setDimension(2); if (c1 >= dimension || c2 >= dimension) { ErrorMessage("Index is too large"); return tmp; } for (int j = 0; j < data.size(); j++) { double[] tt = (double[]) data.get(j); tmp.add(tt[c1], tt[c2]); } return tmp; } /** * Return 3 columns as P2D to show as a X-Y-Z plot * * @param c1 * index of the first column * @param c2 * index of the second column * @param c3 * index of the third column * * @return P3D array with X-Y-Z values. * */ public P2D getP2D(int c1, int c2, int c3) { P2D tmp = new P2D(title + ":" + Integer.toString(c1) + "-" + Integer.toString(c2) + "-" + Integer.toString(c3)); if (c1 >= dimension || c2 >= dimension || c3 >= dimension) { ErrorMessage("Index is too large"); return tmp; } for (int j = 0; j < data.size(); j++) { double[] tt = (double[]) data.get(j); tmp.add(tt[c1], tt[c2], tt[c3]); } return tmp; } /** * Get last dimension of the data (or number of columns). * The stored dimention is the one set after the last call "add", * or if it set manually. * * @return dimension (number of elements in a row) */ public int getDimension() { return dimension; } /** * Get the numbers of columns. * The stored dimention is the one set after the last call "add", * or if it set manually. * * @return dimension (number of elements in a row) */ public int[] getDimensions() { int[] ii = new int[data.size()]; for (int j = 0; j < data.size(); j++) { double[] tt = (double[]) data.get(j); ii[j]=tt.length; } return ii; } /** * Return a specific row as array * * @param row * index of the row * * @return array of values */ public P0D getRow(int row) { P0D tmp = new P0D(title + " row=" + Integer.toString(row)); if (row > data.size()) { ErrorMessage("Index is too large"); return tmp; } double[] tt = (double[]) data.get(row); tmp.setArray(tt); return tmp; } /** * Get data in form of ArrayList * * @return data in form of ArrayList */ public ArrayList getArrayList() { return this.data; } /** * Get the data point set for JAIDA * * @return */ public IDataPointSet getIDataPointSet() { IAnalysisFactory af = IAnalysisFactory.create(); ITree tree = af.createTreeFactory().create(); IDataPointSetFactory dpsf = af.createDataPointSetFactory(tree); IDataPointSet fDps2D = dpsf.create(getTitle(), getTitle(), dimension); for (int i = 0; i < data.size(); i++) { fDps2D.addPoint(); double[] tt = (double[]) data.get(i); for (int j = 0; j < dimension; j++) fDps2D.point(i).coordinate(j).setValue(tt[j]); } return fDps2D; } /** * Adds (appends) the specified element to the end of this list. * * @param values * array of values to be added. * */ public void add(double[] values) { dimension = values.length; data.add(values); } /** * Adds (appends) P0D to the end of this list. * * @param values * array of values to be added. * */ public void add(P0D values) { dimension = values.size(); data.add(values.getArray()); } /** * Sets (replace) the specified row. * * @param index * position index * @param values * array of values to be added. * */ public void set(int index, double[] values) { if (index >= data.size()) { ErrorMessage("Index is too large"); } dimension = values.length; data.set(index, values); } /** * Sets (replace) the specified element with P0D. * * @param index * position index * @param values * array of values to be added. * */ public void set(int index, P0D values) { if (index >= data.size()) { ErrorMessage("Index is too large"); } dimension = values.size(); data.set(index, values.getArray()); } /** * * Read the data from an external source. Old data will be lost. Use "#" or * "*" for comments. Use a space to separate values in columns and new line * to put new row. * * @param br * BufferedReader * * @return zero if success. */ public int read(BufferedReader br) { data.clear(); try { String line; // dis.available() returns 0 if the file does not have more lines. while ((line = br.readLine()) != null) { line = line.trim(); if (!line.startsWith("#") && !line.startsWith("*")) { StringTokenizer st = new StringTokenizer(line); dimension = st.countTokens(); // number of words double[] snum = new double[dimension]; int mm = 0; while (st.hasMoreTokens()) { // make sure there is stuff // to get String tmp = st.nextToken(); // read double double dd = 0; try { dd = Double.parseDouble(tmp.trim()); } catch (NumberFormatException e) { ErrorMessage("Error in reading the line " + Integer.toString(mm + 1)); } snum[mm] = dd; mm++; } // end loop over each line data.add(snum); } // skip # // this statement reads the line from the file and print it to // System.out.println(line); } // dispose all the resources after using them. br.close(); } catch (FileNotFoundException e) { ErrorMessage("File not found!"); e.printStackTrace(); return 2; } catch (IOException e) { e.printStackTrace(); return 1; } return 0; } /** * Read PND from a file. * * The old content will be lost. Use a space to separate values in columns * and new line to put new row. Comment lines starting with "#" and "*" are * ignored. * * * @param sfile * input file * @return zero if success */ public int read(File sfile) { BufferedReader is = PReader.read(sfile); if (is == null) return 1; return read(is); } /** * Read data from URL. Use a space to separate values in columns and new * line to put new row. * * @param url * URL location of input file */ public int read(URL url) { BufferedReader is = PReader.read(url); if (is == null) return 1; return read(is); } /** * Read PND from a GZiped file. It can read URL if the string starts from * http or ftp, otherwise a file on the file system is assumed. *

* Use a space to separate values in columns and new line to put new row. * * @param sfile * File name with input (extension .gz) * @return zero if success */ public int readGZip(String sfile) { BufferedReader is = PReader.readGZip(sfile); if (is == null) return 1; return read(is); } /** * Read PND from a file. It can read URL if the string starts from http or * ftp, otherwise a file on the file system is assumed. *

* The old content will be lost. Use a space to separate values in columns * and new line to put new row. Comment lines starting with "#" and "*" are * ignored. * * @param sfile * File name with input * @return zero if success */ public int read(String sfile) { BufferedReader is = PReader.read(sfile); if (is == null) return 1; return read(is); } /** * Read PND from a GZiped file. The old content will be lost. Use a space to * separate values in columns and ne line to put new row. Comment lines * start from "#" and "*" are ignored. * * @param sfile * File name with input (extension .gz) * @return zero if success */ public int readGZip(File sfile) { BufferedReader is = PReader.readGZip(sfile); if (is == null) return 1; return read(is); } /** * * Read the data from ZIPed external file. Old data will be lost. Use "#" or * "*" for comments. * * @param sfile * File name with the input (extension .zip) * @return zero if success. */ public int readZip(String sfile) { data.clear(); try { ZipFile zf = new ZipFile(sfile); Enumeration entries = zf.entries(); BufferedReader input = new BufferedReader(new InputStreamReader( System.in)); while (entries.hasMoreElements()) { ZipEntry ze = (ZipEntry) entries.nextElement(); // System.out.println("Read " + ze.getName() + "?"); String inputLine = input.readLine(); if (inputLine.equalsIgnoreCase("yes")) { long size = ze.getSize(); if (size > 0) { // System.out.println("Length is " + size); BufferedReader br = new BufferedReader( new InputStreamReader(zf.getInputStream(ze))); String line; while ((line = br.readLine()) != null) { line = line.trim(); if (!line.startsWith("#") && !line.startsWith("*")) { StringTokenizer st = new StringTokenizer(line); dimension = st.countTokens(); // number of words double[] snum = new double[dimension]; int mm = 0; while (st.hasMoreTokens()) { // make sure there // is stuff // to get String tmp = st.nextToken(); // read double double dd = 0; try { dd = Double.parseDouble(tmp.trim()); } catch (NumberFormatException e) { ErrorMessage("Error in reading the line " + Integer.toString(mm + 1)); } snum[mm] = dd; mm++; } // end loop over each line data.add(snum); } // skip # } br.close(); } } } // this statement reads the line from the file and print it to } catch (FileNotFoundException e) { ErrorMessage("File not found!"); e.printStackTrace(); return 2; } catch (IOException e) { e.printStackTrace(); return 1; } return 0; } /** * Write a PND to an external file. Same method as toFile() * * @param name * File name with output */ public void write(String name) { toFile(name); } /** * Write a P0D object to a serialized file * * @param name * serialized file name for output. * * @return zero if no errors */ public int writeSerialized(String name) { return jhplot.io.Serialized.write(this, name); } /** * Read a PND object from a serialized file * * @param name * serialized file name for input. * * @return new PND object */ public PND readSerialized(String name) { return (PND) jhplot.io.Serialized.read(name); } /** * Write a PND to an external file. * * @param name * File name with output */ public void toFile(String name) { Date dat = new Date(); String today = String.valueOf(dat); try { FileOutputStream f1 = new FileOutputStream(new File(name)); PrintStream tx = new PrintStream(f1); tx.println("# DataMelt: output from PND " + this.title); tx.println("# DataMelt: created at " + today); tx.println("# values:"); tx.println("#"); for (int i = 0; i < data.size(); i++) { double[] tt = (double[]) get(i); dimension = tt.length; for (int j = 0; j < dimension; j++) tx.print(tt[j]); tx.print("\n"); } f1.close(); } catch (IOException e) { ErrorMessage("Error in the output file"); e.printStackTrace(); } } /** * Remove a row * * @param index * row index to be removed */ public PND remove(int index) { data.remove(index); return this; } /** * Operations on PND containers: add, subtract, multiply, divide. Keep the * same graphical attributes and title. * * @param pnd * Input PND container for operation * @param what * String representing the operation: "+" add a P0D container to * the original; "-" subtract a P0D from the original; "*" * multiply; "/" divide by P0D * @return original PND after the operation. */ public PND oper(PND pnd, String what) { return oper(pnd, getTitle(), what); } /** * Operations on PND containers: add, subtract, multiply, divide. Keep the * same graphical attributes * * @param pnd * Input PND container for operation * @param title * New title * @param what * String representing the operation: "+" add a P0D container to * the original; "-" subtract a P0D from the original; "*" * multiply; "/" divide by P0D * @return original PND after the operation. */ public PND oper(PND pnd, String title, String what) { what = what.trim(); // first check them if (data.size() != pnd.size()) { ErrorMessage("Sizes of the PNDs are different!"); return this; } // first check them if (dimension != pnd.getDimension()) { ErrorMessage("Dimensions of the PNDs are different!"); return this; } if (what.equals("+")) { for (int i = 0; i < data.size(); i++) { double[] tt1 = (double[]) get(i); double[] tt2 = (double[]) pnd.get(i); for (int j = 0; j < tt1.length; j++) tt1[j] = tt1[j] + tt2[j]; data.set(i, tt1); } return this; } if (what.equals("-")) { for (int i = 0; i < data.size(); i++) { double[] tt1 = (double[]) get(i); double[] tt2 = (double[]) pnd.get(i); for (int j = 0; j < tt1.length; j++) tt1[j] = tt1[j] - tt2[j]; data.set(i, tt1); } return this; } if (what.equals("*")) { for (int i = 0; i < data.size(); i++) { double[] tt1 = (double[]) get(i); double[] tt2 = (double[]) pnd.get(i); for (int j = 0; j < tt1.length; j++) tt1[j] = tt1[j] * tt2[j]; data.set(i, tt1); } return this; } if (what.equals("/")) { for (int i = 0; i < data.size(); i++) { double[] tt1 = (double[]) get(i); double[] tt2 = (double[]) pnd.get(i); for (int j = 0; j < tt1.length; j++) tt1[j] = tt1[j] / tt2[j]; data.set(i, tt1); } return this; } return this; } /** * Scale each element of data * * @param scale * Scale factor * */ public void operScale(double scale) { for (int i = 0; i < data.size(); i++) { double[] tt1 = (double[]) get(i); for (int j = 0; j < tt1.length; j++) tt1[j] = tt1[j] * scale; data.set(i, tt1); } return; } /** * Data size (number of rows) * * @return number of rows */ public int size() { return data.size(); } /** * Create an exact copy of the current P0D. New object is created. * * @param newtitle * new title */ public PND copy(String newtitle) { PND tmp = new PND(newtitle); for (int i = 0; i < data.size(); i++) { double[] tt = (double[]) data.get(i); double[] clone = (double[]) tt.clone(); tmp.add(clone); } return tmp; } /** * Get rows : min is inxluded, max is not; * * @param title * New title * @param indexMin * min index of row * @param indexMax * max index of row * @return new PND with rows indexMin-indexMax **/ public PND getRows(String newtitle, int indexMin, int indexMax) { PND tmp = new PND(newtitle); if (indexMin < 0) { ErrorMessage("Wrong min index"); return null; } if (indexMax > data.size()) { ErrorMessage("Wrong max index"); return null; } ; for (int i = indexMin; i < indexMax; i++) tmp.add(get(i)); return tmp; } /** * Set the data in form of ArrayList * * @param array * ArrayList to be set. */ public void setArrayList(ArrayList array) { this.data = array; } /* * int[][] a = new int[2][4]; * * This two-dimensional array will have two rows and four columns. * * * In Java two-dimensional arrays are implemented is a one-dimensional array * of one-dimensional arrays -- like this. */ /** * Get a double array with values. * * @return double array with values */ public double[][] getArray() { double[][] tmp = new double[data.size()][dimension]; for (int i = 0; i < data.size(); i++) { double[] tt = (double[]) data.get(i); for (int j = 0; j < tt.length; j++) tmp[i][j] = tt[j]; } return tmp; } /** * Set values from double array Old content will be lost. * * @param values * array to be set: [ROWS][dimension]; * * @return PND with new values */ public PND setArray(double[][] values) { if (values[0].length != dimension) { ErrorMessage("Input array has too large dimension"); return this; } data.clear(); for (int i = 0; i < values.length; i++) data.add(values[i]); return this; } /** * Generate error message * * @param a * Message */ private void ErrorMessage(String a) { jhplot.utils.Util.ErrorMessage(a); } /** * Standardize each column. Useful for Neural Network studies. This means * S(i)= (X(i) - mean) / std; i goes from 0 to size(); for each column in * PND. mean - mean value for data in a certain column; std is the standard * deviation. Usually used for neural net to standardize the input variables * (column vectors). Operates on the original data. * * * @return PND after standardize * */ public PND standardize() { int dim = getDimension(); double values[][] = new double[dim][size()]; for (int n = 0; n < dim; n++) { double a[] = new double[size()]; for (int j = 0; j < size(); j++) a[j] = get(j, n); double mean = Statistics.mean(a); double std = Statistics.stddeviation(a); for (int j = 0; j < size(); j++) values[n][j] = (a[j] - mean) / std; } for (int j = 0; j < size(); j++) { double t[] = new double[dim]; for (int n = 0; n < dim; n++) t[n] = values[n][j]; data.set(j, t); } return this; } /** * Rescale the column vectors. S(i)= (X(i) - v[0]) / v[1], where * v[dimension] [2] is the 2D array returned by this function to be able * calculate X(i) back. Usually used for a neural net (rescaling of the * output). * *

* * @param type * 0: is ths standard rescaling, i.e. all columns are rescaled to * the range [0,1] This is done as: v[0] is the min value of * X(i), v[1] is the range (max-min). *

* type 1: midrange rescaling, i.e. all values are in the range * [-1,1]. v[0] is 0.5*(min+max), while [1] is (max-min) /2 * * * @return v[][] used to rescale the data: v[column][0] gives v[0], * v[column][1] given by v[1]. Use this array to convert the data * back. */ public double[][] rescale(int type) { int dim = getDimension(); double values[][] = new double[dim][size()]; double range[] = new double[dim]; double min[] = new double[dim]; double max[] = new double[dim]; for (int n = 0; n < dim; n++) { double a[] = new double[size()]; for (int j = 0; j < size(); j++) a[j] = get(j, n); min[n] = DoubleArray.min(a); max[n] = DoubleArray.max(a); range[n] = max[n] - min[n]; if (type == 1) { // midrange [-1-1] min[n] = 0.5 * (min[n] + max[n]); range[n] = 0.5 * range[n]; } for (int j = 0; j < size(); j++) values[n][j] = (a[j] - min[n]) / range[n]; } // collect back for (int j = 0; j < size(); j++) { double t[] = new double[dim]; for (int n = 0; n < dim; n++) t[n] = values[n][j]; data.set(j, t); } double tmp[][] = new double[dim][2]; for (int n = 0; n < dim; n++) { tmp[n][0] = min[n]; tmp[n][1] = range[n]; } return tmp; } /** * Return H1D histogram with PND content. All values are added. Histogram * range is defined by Min and Max values. * * @param bins * Number of bins for the histogram. * @param min * Min value of histogram * @param max * Max value of histogram * @return H2D histogram filled with P0D. */ public H1D getH1D(int bins, double min, double max) { H1D h1d = new H1D(this.title, bins, min, max); for (int n = 0; n < getDimension(); n++) { for (int j = 0; j < size(); j++) h1d.fill((double) get(j, n)); } return h1d; } /** * Make a histogram from a column of PND. * * @param bins * Number of bins * @param min * Min value * @param max * Max value * @param column * column of PND ( maxValue) { maxValue = get(j, n); } } } return maxValue; } /** * Get max value * * @return */ public double getMin() { double minValue = get(0, 0); for (int n = 0; n < getDimension(); n++) { for (int j = 0; j < size(); j++) { if (get(j, n) < minValue) { minValue = get(j, n); } } } return minValue; } /** * Get min and max at the same time. */ private void getMinMax() { min = get(0, 0); min = max; for (int n = 0; n < getDimension(); n++) { for (int j = 0; j < size(); j++) { if (get(j, n) < min) { min = get(j, n); } if (get(j, n) > max) { max = get(j, n); } } } } /** * This is an inverse operation to rescale(type) function. You should give * array v[2], from which the original data can be calculated. Each column * after the rescaling will be transformed to X(i)=S(i)*v[1]+v[0] (we drop * here index for rows). * * @param v * array used to rescale the data. applied as X(i)=S(i)*v[1]+v[0] * @return PND after rescaling */ public PND rescale(double[][] v) { int dim = getDimension(); double values[][] = new double[dim][size()]; for (int n = 0; n < dim; n++) { double a[] = new double[size()]; for (int j = 0; j < size(); j++) a[j] = get(j, n); for (int j = 0; j < size(); j++) values[n][j] = a[j] * v[n][1] + v[n][0]; } // collect back for (int j = 0; j < size(); j++) { double t[] = new double[dim]; for (int n = 0; n < dim; n++) t[n] = values[n][j]; data.set(j, t); } return this; } /** * Test * * @param args */ public static void main(String[] args) { HPlot c1 = new HPlot("Canvas", 600, 400); c1.visible(true); c1.setAutoRange(); PND p0 = new PND("Example"); p0.add(new double[] { 1, 2, 3 }); p0.add(new double[] { 2, 5, 1 }); p0.add(new double[] { 7, 6, 4 }); p0.add(new double[] { 10, 2, 0 }); p0.add(new double[] { 4, 8, 2 }); System.out.println(p0.toString()); c1.setNameX("X"); c1.setNameY("Y"); p0.print(); P0D ppp = p0.getP0D(1); // drow as histogram H1D h1 = ppp.getH1D(100); c1.draw(h1); } /** * Show container to a Table in a separate Frame. The numbers are formatted * to scientific format. One can sort and search the data in this table (but * not modify) */ public void toTable() { new HTable(this); } /** * Show online documentation. */ public void doc() { String a = this.getClass().getName(); a = a.replace(".", "/") + ".html"; new HelpBrowser(HelpBrowser.JHPLOT_HTTP + a); } }