package scalaSci.math.plot;
import java.awt.*;
import javax.swing.JFrame;
import javax.swing.JPanel;
import org.matheclipse.symja.OutputTextPane;
import org.scilab.forge.jlatexmath.TeXConstants;
import org.scilab.forge.jlatexmath.TeXFormula;
import org.scilab.forge.jlatexmath.TeXIcon;
// objects. In order to implement the grid like structure of Matlab subplots a constructor
// is defined that builds these objects from an array of graphic panel objects of the same type.
// The FrameView class represents plotting frame objects similar to Matlab figures.
// They can contain a rectangular grid of subplot objects.
import scalaExec.Interpreter.GlobalValues;
import scalaSci.math.plot.plotObjects.Axis;
import scalaSci.math.plot.plotObjects.LatexImage;
import scalaSci.math.plot.plotObjects.texLabel;
public class plot {
static public boolean scatterPlotOn = false;
static int currentFigTableIndex=0; // the identifier of the working figure as its index at the Figure table
static int currentPlotCnt2D = 0; // holds the number of the existing 2D figure objects
static int currentPlotCnt3D = 0; // holds the number of the existing 3D figure objects
static int currentPlotCnt = 0; // a counter for the current number of figures
static int maxNumberOfFigs = 20; // maximum number of figure frames
static double figTableIncreaseFactor = 1.5; // factor to increase dynamically the figure table size
static PlotPanel [] [] [] allPlots = null; // all the plot objects that belong to each Matlab-like figure object, e.g. allPlots[f][] is the table with the references to the plots
static FrameView [] allFrames = null; // holds the pointers to all the frames for all the figure objects
static PlotPanel currentPlot = null; // the handle where plot operations are directed
static boolean new_figure = true; // controls whether to create a new figure or to plot upon an existing one
static boolean holdOnMode = true; // controls holding previous plots, used to implement Matlab's hold("on"), hold("off")
// plots all points, however this can be resource wasteful for large signals
static public boolean fullPlotsOn() {
boolean prevState = PlotGlobals.skipPointsOnPlot;
PlotGlobals.skipPointsOnPlot = false;
return prevState;
}
static public boolean fastPlotsOn() {
boolean prevState = PlotGlobals.skipPointsOnPlot;
PlotGlobals.skipPointsOnPlot = true;
return prevState;
}
static public int setMaximumPlotPoints(int newMaxPointsToPlot) {
int prevMaxPointsToPlot = PlotGlobals.limitPlotPoints;
PlotGlobals.limitPlotPoints = newMaxPointsToPlot;
return prevMaxPointsToPlot;
}
// controls for 3-D plots the max points at the X-dimension
static public int setMaximumPlotXPoints(int newMaxPointsXToPlot) {
int prevMaxXPointsToPlot = PlotGlobals.limitPlotPointsX;
PlotGlobals.limitPlotPointsX = newMaxPointsXToPlot;
return prevMaxXPointsToPlot;
}
// controls for 3-D plots the max points at the Y-dimension
static public int setMaximumPlotYPoints(int newMaxPointsYToPlot) {
int prevMaxYPointsToPlot = PlotGlobals.limitPlotPointsY;
PlotGlobals.limitPlotPointsY = newMaxPointsYToPlot;
return prevMaxYPointsToPlot;
}
static public PlotPanel getPlot(){
return currentPlot;
}
static public Axis getXAxis() {
return currentPlot.getAxis(0);
}
static public Axis getYAxis() {
return currentPlot.getAxis(1);
}
static public Axis getZAxis() {
return currentPlot.getAxis(2);
}
// turn scatter plots on, in scatter plots points are not connected by a line
static public boolean scatterPlotsOn() {
boolean prevLineMode = scatterPlotOn;
scatterPlotOn = true;
return prevLineMode;
}
// turn line plots off, in line plots points are connected by a line
static public boolean linePlotsOn() {
boolean prevLineMode = scatterPlotOn;
scatterPlotOn = false;
return prevLineMode;
}
static public double [] arrToDouble(float [] x) // convert float [] array to double []
{
int N = x.length;
double [] dx = new double[N];
for (int k=0; k<N; k++)
dx[k] = x[k];
return dx;
}
static public double [][] arrToDoubleDouble(float [][] x) // convert float [][] array to double [][]
{
int N = x.length; int M=x[0].length;
double [] [] dxy = new double[N][M];
for (int r=0; r<N; r++)
for (int c=0; c<M; c++)
dxy[r][c] = x[r][c];
return dxy;
}
public static void subplot( int p) {
int r = p / 100;
int rem = p % 100;
int c = rem / 10;
int id = rem % 10;
subplot2d(r, c, id);
}
public static void subplot2d( int p) {
int r = p / 100;
int rem = p % 100;
int c = p / 10;
int id = rem % 10;
subplot2d(r, c, id);
}
public static void subplot3d( int p) {
int r = p / 100;
int rem = p % 100;
int c = p / 10;
int id = rem % 10;
subplot3d(r, c, id);
}
// increase the size of the global figure table when required
public static void increaseFigTable() {
int maxNumberOfFigsLarge = (int)(maxNumberOfFigs*figTableIncreaseFactor); // update number of figs
FrameView [] cpAllFrames = new FrameView[maxNumberOfFigsLarge]; // table that holds indices to the new figure frames
for (int k=0; k<allFrames.length; k++) // copy previous to enlarged
cpAllFrames[k] = allFrames[k];
PlotPanel [][][] cpAllPlots = new PlotPanel[maxNumberOfFigsLarge][][];
for (int k=0; k<maxNumberOfFigs; k++) // copy previous to enlarged
cpAllPlots[k] = allPlots[k];
for (int k=maxNumberOfFigs; k<maxNumberOfFigsLarge; k++) { // new entries to nulls
cpAllPlots[k] = null;
cpAllFrames[k] = null;
}
maxNumberOfFigs = maxNumberOfFigsLarge; // update figure table size
// enlarged tables become the current
allPlots = cpAllPlots;
allFrames = cpAllFrames;
}
// increase the Figure tables to cover the specified Figure number
public static void increaseFigTableSpecifiedSize(int specifiedFigNo) {
if (specifiedFigNo <= maxNumberOfFigs)
return; // specified size smaller than the current Figure table size
int maxNumberOfFigsLarge = (int)(figTableIncreaseFactor*specifiedFigNo); // update number of figs
FrameView [] cpAllFrames = new FrameView[maxNumberOfFigsLarge];
for (int k=0; k<allFrames.length; k++) // copy previous to enlarged
cpAllFrames[k] = allFrames[k];
PlotPanel [][][] cpAllPlots = new PlotPanel[maxNumberOfFigsLarge][][];
for (int k=0; k<maxNumberOfFigs; k++) // copy previous to enlarged
cpAllPlots[k] = allPlots[k];
for (int k=maxNumberOfFigs; k<maxNumberOfFigsLarge; k++) { // new entries to nulls
cpAllPlots[k] = null;
cpAllFrames[k] = null;
}
maxNumberOfFigs = maxNumberOfFigsLarge; // update figure table size
// enlarged tables become the current
allPlots = cpAllPlots;
allFrames = cpAllFrames;
}
// initializes the ploting system
public static void initplots() {
if (allFrames == null) { // plotting system not initialized yet
allPlots = new PlotPanel[maxNumberOfFigs][][]; // all the "subplot" objects
for (int k=0; k<maxNumberOfFigs; k++)
allPlots[k] = null;
allFrames = new FrameView[maxNumberOfFigs]; // all the "figure" objects
for (int k=0; k<maxNumberOfFigs; k++)
allFrames[k] = null;
currentPlotCnt2D = 0;
currentPlotCnt3D = 0;
currentPlotCnt = 0;
currentFigTableIndex = 0;
currentPlot = null;
new_figure = true;
}
}
// returns the current number of figure objects (e.g. FrameView objects), is the number of non-null entries of the allFrames[] table
public static int getFigCount() {
int figCnt=0;
for (int k=0; k<maxNumberOfFigs; k++)
if (allFrames[k] != null)
figCnt++;
return figCnt;
}
// create a new 2D figure object if we do not focus on an existing one
public static void newPlot2D() {
initplots(); // init plotting system if not yet initialized
// if either we do not have a current 2D ploting panel or a new figure is explicitly requested we create a new figure
if ( (currentPlot == null) || (!(currentPlot instanceof Plot2DPanel) || new_figure)) {
// assume a subplot2D(1,1,1), i.e. the array of 2D subplots is initialized to a single subplot for the whole figure
Plot2DPanel [][] subplots2D = new Plot2DPanel[1][1];
Plot2DPanel newPanel = new Plot2DPanel();
subplots2D[0][0] = newPanel;
// construct the new 2D plot frame
Plot2DPanel newplot = new Plot2DPanel(subplots2D, PlotPanel.NORTH); // create a new 2D figure object
currentFigTableIndex = getFigureId(); // request an available free figure identifier
// initialize the frame window of the new figure
String figTitle = "Fig. "+(currentFigTableIndex+1);
FrameView f = new FrameView(figTitle, newplot, currentFigTableIndex);
if (GlobalValues.smallScalaImage != null)
f.setIconImage(GlobalValues.smallScalaImage.getScaledInstance(400,400, 0));
allFrames[currentFigTableIndex] = f; // keep the frame window of the new figure
allPlots[currentFigTableIndex] = subplots2D; // keep the subplot structure
currentPlotCnt++;
currentPlotCnt2D++; // a new 2D plot is created
new_figure = false;
currentPlot = subplots2D[0][0]; // focus on a component with a canvas
currentPlot.setLegendOrientation("SOUTH");
}
}
// create a new 3D figure object if we do not focus on an existing one
public static void newPlot3D() {
initplots(); // init plotting system if not yet initialized
// if either we do not have a current 3D ploting panel or a new figure is explicitly requested we create a new figure
if ( (currentPlot == null) || (!(currentPlot instanceof Plot3DPanel) || new_figure)) {
// assume a subplot3D(1,1,1)
Plot3DPanel [][] subplots3D = new Plot3DPanel[1][1]; // the array of 3D-subplots
subplots3D[0][0] = new Plot3DPanel();
// construct the new 3D plot frame
Plot3DPanel newPlot = new Plot3DPanel(subplots3D, PlotPanel.NORTH); // create a new 3D figure object
String figTitle = "Fig. "+(currentFigTableIndex+1);
FrameView f = new FrameView(figTitle, newPlot, currentFigTableIndex);
if (GlobalValues.smallScalaImage != null)
f.setIconImage(GlobalValues.smallScalaImage);
currentFigTableIndex = getFigureId(); // get a free figure id
allFrames[currentFigTableIndex] = f; // keep the frame window of the new figure
allPlots[currentFigTableIndex] = subplots3D; // keep the subplot structure
currentPlotCnt3D++; // a new 3D plot is created
currentPlotCnt++;
new_figure = false;
currentPlot = subplots3D[0][0]; // focus on a component with a canvas
currentPlot.setLegendOrientation("SOUTH");
}
}
// closes all the available figure objects
public static void closeAll() {
if (allFrames != null)
for (int figId=0; figId<maxNumberOfFigs; figId++)
if (allFrames[figId] != null)
close(figId+1);
allFrames = null;
}
public static void close(String all) {
if (all.equalsIgnoreCase("all"))
closeAll();
}
// returns an Id of an unused slot for figure
public static int getFigureId() {
boolean figIdsRemain = false; // remain empty slots for new figures
for (int k=0; k<maxNumberOfFigs; k++) {
if (allFrames[k]==null) {
currentFigTableIndex = k;
figIdsRemain = true;
currentFigTableIndex = k;
break;
}
}
if (figIdsRemain == false) { // increase the size of figure tables
int prevFigCnt = maxNumberOfFigs; // previous count of Figures
increaseFigTable(); // increase the size of figure table
currentFigTableIndex = prevFigCnt; // return the first id from the enlarged region
}
return currentFigTableIndex;
}
// constructs a 2d figure object. Returns the figure id
static public int figure() {
return figure2d();
}
// constructs a new figure 2D object with a single subplot panel, i.e. subplot(1,1,1). Returns the figure id
static public int figure2d() { // initialize flags for creating a new figure at the next ploting operation
initplots();
new_figure=true;
int currentFigTableIndex = getFigureId(); // returns the id of the available figure
createSubplot2D(1,1,1, currentFigTableIndex);
return currentFigTableIndex+1;
}
// constructs a new figure 3D object with a single subplot panel, i.e. subplot(1,1,1). Returns the figure id
static public int figure3d() { // initialize flags for creating a new 3D figure at the next ploting operation
initplots();
new_figure=true;
int currentFigTableIndex = getFigureId(); // returns the id of the available figure
createSubplot3D(1,1,1, currentFigTableIndex);
return currentFigTableIndex+1;
}
// focus on the figure with the identifier figId
static public PlotPanel figure(int figId) {
initplots();
if (figId < 1) // assume the smallest figId when a zero or negative figId is requested
figId = 1;
if (figId > maxNumberOfFigs) // increase Figure table size
increaseFigTableSpecifiedSize(figId);
int figMinus1 = figId-1; // indexes start at 0, figures numbered from 1 according to Matlab conventions
if (allPlots[figMinus1] != null) { // figure id exists
currentPlot = allPlots[figMinus1][0][0]; // the requested figure panel
// if the figure id exists and is Plot3DPanel then it should be closed explicitly in order to use the figure id for 3D plots
if (currentPlot instanceof Plot3DPanel)
return null;
return currentPlot;
}
else { // we do not have the requested figure object, create it explicitly
currentFigTableIndex = figMinus1;
return createSubplot2D(1,1,1, currentFigTableIndex);
}
}
static public int figure2d(int figId) {
return figure2d();
}
// focus on the figure with the identifier figId
static public PlotPanel figure3d(int figId) {
initplots();
if (figId < 1) // assume the smallest figId when a zero or negative figId is requested
figId = 1;
int figMinus1 = figId-1; // indexes start at 0, figures numbered from 1 according to Matlab conventions
if (allPlots[figMinus1] != null) { // figure id exists
currentPlot = allPlots[figMinus1][0][0]; // the requested figure panel
// if the figure id exists and is Plot2DPanel then it should be closed explicitly in order to use the figure id for 3D plots
if (currentPlot instanceof Plot2DPanel)
return null;
return currentPlot;
}
else { // we do not have the requested figure object, create it explicitly
currentFigTableIndex = figMinus1;
return createSubplot3D(1,1,1, currentFigTableIndex);
}
}
/*
var N=pow(2, 15).toInt; var t=linspace(0, 10, N);
var (noise, sig) = (vrand(N), sin(2.3*t))
var (fftNoise, fftSig) = (fft(noise), fft(sig))
figure(1); subplot(2,1,1); plot(t, sig, Color.BLUE, "signal"); hold("on"); plot(t, noise, Color.RED, "noise");
subplot(2,1,2); plot(fftSig, Color.BLUE, "FFT of signal"); hold("on"); plot(fftNoise, Color.RED, "FFT of noise")
*/
static public boolean hold(boolean newHoldState) {
boolean oldHoldState = holdOnMode;
holdOnMode = newHoldState;
return oldHoldState;
}
static public String hold(String newHoldState) {
boolean oldHoldState = holdOnMode;
boolean newHoldModeToSet = false;
if (newHoldState.equalsIgnoreCase("on") || newHoldState.equalsIgnoreCase("1"))
newHoldModeToSet = true;
holdOnMode = newHoldModeToSet;
return oldHoldState==true?"on":"off";
}
static public void title(String titleStr) {
int plotCnt = currentFigTableIndex;
if (plotCnt < 0 )
plotCnt = 0;
FrameView currentView = allFrames[plotCnt];
if (currentView != null)
currentView.setTitle(titleStr);
}
// sets the title of the figure frame with identofoer figId
static public void title(int figId, String titleStr) {
FrameView currentView = allFrames[figId-1];
if (currentView != null)
currentView.setTitle(titleStr);
}
/*
t = inc(0, 0.01, 10); x = sin(0.12*t); plot(x);
*/
// clears all the plots from the figure with figId
static public void clf(int figId) {
FrameView figFrame = allFrames[figId-1]; // the frame of the figure
if (figFrame == null) return; // no such figure
PlotPanel [][] plots = allPlots[figId-1];
int numRows = plots.length;
int numCols = plots[0].length;
for (int row=0; row < numRows; row++)
for (int col=0; col < numCols; col++) { // for all subplots
PlotPanel currentPanel = plots[row][col];
currentPanel.removeAllPlots();
}
}
// clears all the plots from the reference plotPanel
static public void clf(PlotPanel plotPanel) {
plotPanel.removeAllPlots();
}
// clears all the plot with identifier plotId, from the figure with identifier figId, at subplot id: [xId, yId]
// the numbering of plot ids starts at 1 (as the fig ids)
static public void clf(int figId, int xId, int yId, int plotId) {
FrameView figFrame = allFrames[figId-1]; // the frame of the figure
if (figFrame == null) return; // no such figure
PlotPanel [][] plots = allPlots[figId-1];
int numRows = plots.length;
int numCols = plots[0].length;
if (numRows > yId || numCols > xId) // requested subplot not exists
return;
PlotPanel currentPanel = plots[xId][yId];
currentPanel.remove(plotId-1);
}
// clears the plot with identifier plotId, from the figure with identifier figId
// the numbering of plot ids starts at 1 (as the fig ids)
// Example:
// var x=linspace(0, 2, 1000); var y = sin(3.4*x); plot(x, y); hold("on")
// plot(x, 3*sin(8*y), Color.BLUE)
// clf(1,1) // clears the first plot
static public void clf(int figId, int plotId) {
FrameView figFrame = allFrames[figId-1]; // the frame of the figure
if (figFrame == null) return; // no such figure
PlotPanel [][] plots = allPlots[figId-1];
int numRows = plots.length;
int numCols = plots[0].length;
for (int row=0; row < numRows; row++)
for (int col=0; col < numCols; col++) { // for all subplots
PlotPanel currentPanel = plots[row][col];
currentPanel.removePlot(plotId-1);
}
}
// clears the plot with identifier plotId, from the figure with identifier figId, at subplot id: [xId, yId]
// the numbering of plot ids starts at 1 (as the fig ids)
static public void clf(int figId, int xId, int yId) {
FrameView figFrame = allFrames[figId-1]; // the frame of the figure
if (figFrame == null) return; // no such figure
PlotPanel [][] plots = allPlots[figId-1];
int numRows = plots.length;
int numCols = plots[0].length;
if (yId > numRows || xId > numCols) // requested subplot not exists
return;
PlotPanel currentPanel = plots[yId-1][xId-1];
currentPanel.removeAllPlots();
}
// creates a Matlab-like placement of multiple subplots in a figure with id figureId
// the function overwrites (i.e. disposes) any plot object that was residing on slots allFrames[figureId], allPlots[figureId]
// sets the currentPlot member variable to the focused subplot object
// a figure identifier to use is explicitly requested
static public PlotPanel createSubplot2D(int rows, int cols, int focusSubPlot, int figureId) {
initplots();
// create new figure
Plot2DPanel [] [] newPlot2DPanel = new Plot2DPanel[rows][cols];
for (int ni=0; ni<rows; ni++) // initialize the new plot panel
for (int mi=0; mi<cols; mi++)
newPlot2DPanel[ni][mi] = new Plot2DPanel();
currentFigTableIndex = figureId; // the requested figure id to create
String figTitle = "Fig. "+(currentFigTableIndex+1);
// construct the new 2D plot frame
Plot2DPanel newplot = new Plot2DPanel(newPlot2DPanel, PlotPanel.NORTH); // create a new 2D figure object
FrameView fprev = allFrames[currentFigTableIndex]; // any existing frame at that slot
if (fprev == null) {
currentPlotCnt2D++;
currentPlotCnt++;
}
else { // dispose the previous frameView
fprev.dispose();
}
FrameView f = new FrameView(figTitle, newplot, currentFigTableIndex);
f.setBackground(Color.WHITE);
allFrames[currentFigTableIndex] = f; // keep the currently constructed figure frame
allPlots[currentFigTableIndex] = newPlot2DPanel; // keep the current 2D figure array of plot panels
new_figure = false; // avoid creating new figure panel for subsequent calls
// adjust the currentPlot parameter to point to the focused subplot requested by the focusSubPlot parameter
int rowNo = (int)(focusSubPlot / cols);
if (rowNo*cols == focusSubPlot) rowNo--;
int colNo = (int)(focusSubPlot - rowNo*cols) - 1;
currentPlot = newPlot2DPanel[rowNo][colNo];
currentPlot.setLegendOrientation("SOUTH");
return (PlotPanel) newplot;
}
// creates a Matlab-like placement of multiple subplots in a figure with id figureId
// the function overwrites any plot object that was residing on slots allFrames[currentFigTableIndex], allPlots[currentFigTableIndex]
// sets the currentPlot member variable to the focused subplot object
// a figure identifierto use is explicitly requested
static public PlotPanel createSubplot3D(int rows, int cols, int focusSubPlot, int figureId) {
initplots();
// create new figure
Plot3DPanel [] [] newPlot3DPanel = new Plot3DPanel[rows][cols];
for (int ni=0; ni<rows; ni++) // initialize the new plot panel
for (int mi=0; mi<cols; mi++)
newPlot3DPanel[ni][mi] = new Plot3DPanel();
currentFigTableIndex = figureId; // the requested figure id to create
String figTitle = "Fig. "+(currentFigTableIndex+1);
// construct the new 3D plot frame
Plot3DPanel newplot = new Plot3DPanel(newPlot3DPanel, PlotPanel.NORTH); // create a new 3D figure object
FrameView fprev = allFrames[currentFigTableIndex]; // any existing frame at that slot
if (fprev == null) {
currentPlotCnt3D++;
currentPlotCnt++;
}
else { // dispose the previous frameView
fprev.dispose();
}
FrameView f = new FrameView(figTitle, newplot, currentFigTableIndex);
allFrames[currentFigTableIndex] = f; // keep the currently constructed figure frame
allPlots[currentFigTableIndex] = newPlot3DPanel; // keep the current 3D figure array of plot panels
new_figure = false; // avoid creating new figure panel for subsequent calls
// adjust the currentPlot parameter to point to the focused subplot requested by the focusSubPlot parameter
int rowNo = (int)(focusSubPlot / cols);
if (rowNo*cols == focusSubPlot) rowNo--;
int colNo = (int)(focusSubPlot - rowNo*cols) - 1;
currentPlot = newPlot3DPanel[rowNo][colNo];
currentPlot.setLegendOrientation("SOUTH");
return (PlotPanel) newplot;
}
// creates a Matlab-like placement of multiple subplots in the current Figure with index currentFigTableIndex
// returns the id of the figure object
static public int Subplot2D(int rows, int cols, int focusSubPlot) {
initplots();
if (allFrames[currentFigTableIndex] == null) { // create new 2D-figure panel
// create new figure
Plot2DPanel [] [] newPlot2DPanel = new Plot2DPanel[rows][cols];
for (int ni=0; ni<rows; ni++) // initialize the new plot panel
for (int mi=0; mi<cols; mi++)
newPlot2DPanel[ni][mi] = new Plot2DPanel();
// construct the new 2D plot frame
currentPlotCnt2D++;
currentPlotCnt++;
Plot2DPanel newplot = new Plot2DPanel(newPlot2DPanel, PlotPanel.NORTH); // create a new 2D figure object
String figTitle = "Fig. "+(currentFigTableIndex+1);
FrameView f = new FrameView(figTitle, newplot, currentFigTableIndex);
allFrames[currentFigTableIndex] = f;
allPlots[currentFigTableIndex] = newPlot2DPanel; // keep the current 2D figure frame
new_figure = false; // avoid creating new figure panel for subsequent calls
// create the objects of the current plot. These are reused at subsequent calls of subplot2D()
int rowNo = (int)(focusSubPlot / cols);
if (rowNo*cols == focusSubPlot) rowNo--;
int colNo = (int)(focusSubPlot - rowNo*cols) - 1;
currentPlot = newPlot2DPanel[rowNo][colNo];
currentPlot.setLegendOrientation("SOUTH");
}
else { // either focus on the requested plot if the subplot grid structure matches,
// or otherwise create a new subplot structure
Plot2DPanel [][] currentPlot2DPanel = (Plot2DPanel[][]) allPlots[currentFigTableIndex];
Plot2DPanel [] [] newPlot2DPanel = currentPlot2DPanel;
int yGrid = currentPlot2DPanel.length;
int xGrid = currentPlot2DPanel[0].length;
if (yGrid != rows || xGrid != cols) { // a grid of different size is requested
newPlot2DPanel = new Plot2DPanel[rows][cols];
// dispose the previous frameView object
FrameView pf = allFrames[currentFigTableIndex];
pf.dispose();
// create new figure
for (int ni=0; ni<rows; ni++) // initialize the new plot panel
for (int mi=0; mi<cols; mi++)
newPlot2DPanel[ni][mi] = new Plot2DPanel();
Plot2DPanel newplot = new Plot2DPanel(newPlot2DPanel, PlotPanel.NORTH); // create a new 2D figure object
String figTitle = "Fig. "+(currentFigTableIndex+1);
FrameView f = new FrameView(figTitle, newplot, currentFigTableIndex);
f.setBackground(Color.WHITE);
allFrames[currentFigTableIndex] = f;
allPlots[currentFigTableIndex] = newPlot2DPanel; // keep the current 2D figure frame
new_figure = false;
}
int rowNo = (int)(focusSubPlot / cols);
if (rowNo*cols == focusSubPlot) rowNo--;
int colNo = (int)(focusSubPlot - rowNo*cols) - 1;
currentPlot = newPlot2DPanel[rowNo][colNo];
currentPlot.setLegendOrientation("SOUTH");
}
return currentFigTableIndex;
}
// creates a Matlab-like placement of multiple subplots in a figure.
// returns the id of the figure object
static public int Subplot3D(int rows, int cols, int focusSubPlot) {
initplots();
if (allFrames[currentFigTableIndex] == null) { // create new 3D-figure panel
// create new figure
Plot3DPanel [] [] newPlot3DPanel = new Plot3DPanel[rows][cols];
for (int ni=0; ni<rows; ni++) // initialize the new plot panel
for (int mi=0; mi<cols; mi++)
newPlot3DPanel[ni][mi] = new Plot3DPanel();
// construct the new 3D plot frame
currentPlotCnt3D++;
currentPlotCnt++;
Plot3DPanel newplot = new Plot3DPanel(newPlot3DPanel, PlotPanel.NORTH); // create a new 3D figure object
String figTitle = "Fig. "+(currentFigTableIndex+1);
FrameView f = new FrameView(figTitle, newplot, currentFigTableIndex);
f.setBackground(Color.WHITE);
allFrames[currentFigTableIndex] = f;
allPlots[currentFigTableIndex] = newPlot3DPanel; // keep the current 3D figure frame
new_figure = false; // avoid creating new figure panel for subsequent calls
// create the objects of the current plot. These are reused at subsequent calls of subplot3D()
int rowNo = (int)(focusSubPlot / cols);
if (rowNo*cols == focusSubPlot) rowNo--;
int colNo = (int)(focusSubPlot - rowNo*cols) - 1;
currentPlot = newPlot3DPanel[rowNo][colNo];
currentPlot.setLegendOrientation("SOUTH");
}
else { // either focus on the requested plot if the subplot grid structure matches,
// or otherwise create a new subplot structure
Plot3DPanel [][] currentPlot3DPanel = (Plot3DPanel[][]) allPlots[currentFigTableIndex];
Plot3DPanel [] [] newPlot3DPanel = currentPlot3DPanel;
int yGrid = currentPlot3DPanel.length;
int xGrid = currentPlot3DPanel[0].length;
if (yGrid != rows || xGrid != cols) { // a grid of different size is requested
newPlot3DPanel = new Plot3DPanel[rows][cols];
// dispose the previous frameView object
FrameView pf = allFrames[currentFigTableIndex];
pf.dispose();
// create new figure
for (int ni=0; ni<rows; ni++) // initialize the new plot panel
for (int mi=0; mi<cols; mi++)
newPlot3DPanel[ni][mi] = new Plot3DPanel();
Plot3DPanel newplot = new Plot3DPanel(newPlot3DPanel, PlotPanel.NORTH); // create a new 3D figure object
String figTitle = "Fig. "+(currentFigTableIndex+1);
FrameView f = new FrameView(figTitle, newplot, currentFigTableIndex);
allFrames[currentFigTableIndex] = f;
allPlots[currentFigTableIndex] = newPlot3DPanel; // keep the current 3D figure frame
new_figure = false;
}
int rowNo = (int)(focusSubPlot / cols);
if (rowNo*cols == focusSubPlot) rowNo--;
int colNo = (int)(focusSubPlot - rowNo*cols) - 1;
currentPlot = newPlot3DPanel[rowNo][colNo];
currentPlot.setLegendOrientation("SOUTH");
}
return currentFigTableIndex;
}
// overloaded call
static public void subplot(int rows, int cols, int focusSubPlot) {
Subplot2D(rows, cols, focusSubPlot);
}
// overloaded call
static public void subplot2D(int rows, int cols, int focusSubPlot) {
Subplot2D(rows, cols, focusSubPlot);
}
// overloaded call
static public void subplot2d(int rows, int cols, int focusSubPlot) {
Subplot2D(rows, cols, focusSubPlot);
}
// overloaded call
static public void subplot3D(int rows, int cols, int focusSubPlot) {
Subplot3D(rows, cols, focusSubPlot);
}
// overloaded call
static public void subplot3d(int rows, int cols, int focusSubPlot) {
Subplot3D(rows, cols, focusSubPlot);
}
// closes the current figure
static public int close() {
// find next usable plot
int currentFigSlotExamined = currentPlotCnt-1;
FrameView closingFrameView = allFrames[currentFigTableIndex]; // the frame view of the current figure
// we have a current view, close it, and refocus on another figure
if (closingFrameView != null) {
closingFrameView.dispose();
if (allPlots[currentFigTableIndex][0][0] instanceof Plot2DPanel)
currentPlotCnt2D--;
else
currentPlotCnt3D--;
allPlots[currentFigTableIndex] = null;
allFrames[currentFigTableIndex] = null;
currentPlotCnt--; // one less plot
boolean atLeastOnefigureRemains = false;
for (int k=0; k<maxNumberOfFigs; k++) { // scan all possible slots
if (allFrames[currentFigSlotExamined] != null) { // we have found an unused slot for focusing figure
atLeastOnefigureRemains = true;
break;
}
if (currentFigSlotExamined < 0) // cycle from the highest position
currentFigSlotExamined = maxNumberOfFigs-1;
} // scan all possible slots
if (atLeastOnefigureRemains == true) { // focus on the detected "survived" figure object
PlotPanel [][] currentPlotPanel = (PlotPanel[][]) allPlots[currentFigSlotExamined];
currentPlot = currentPlotPanel[0][0]; // make the first subplot of the figure object as the current one
currentPlot.setLegendOrientation("SOUTH");
}
} // we have a current view, close it, and refocus on another figure
currentFigTableIndex = currentFigSlotExamined;
return currentFigTableIndex+1;
}
// close an explicitly requested figure id
// it focuses automatically on the previous figure object which it returns
static public int close(int figId) {
int currentFigSlotExamined = currentPlotCnt-1;
if (allFrames != null) { // plot system inited
int figMinusOne = figId-1;
FrameView closingFrameView = allFrames[figMinusOne];
// find next usable plot
int len1 = allPlots[figMinusOne][0].length;
int len2 = allPlots[figMinusOne].length;
if (closingFrameView != null) { // figure frame exists
closingFrameView.dispose();
for (int i=0; i<len2; i++)
for (int j=0; j<len1; j++)
allPlots[figMinusOne][i][j] = null;
allPlots[figMinusOne] = null; // TODOSterg: handle closing properly
allFrames[figMinusOne] = null;
currentPlotCnt--; // one less plot
boolean atLeastOnefigureRemains = false;
for (int k=0; k<maxNumberOfFigs; k++) { // scan all possible slots
if (allFrames[currentFigSlotExamined] != null) { // we have found an unused slot for focusing figure
atLeastOnefigureRemains = true;
break;
}
currentFigSlotExamined--; // check lowest figure id
currentFigTableIndex = currentFigSlotExamined;
if (currentFigSlotExamined < 0) // cycle from the highest position
{
currentFigTableIndex = currentFigSlotExamined = maxNumberOfFigs-1;
}
} // scan all possible slots
if (atLeastOnefigureRemains == true) { // focus on the detected "survived" figure object
PlotPanel [][] currentPlotPanel = (PlotPanel[][]) allPlots[currentFigSlotExamined];
currentPlot = currentPlotPanel[0][0]; // make the first subplot of the figure object as the current one
currentPlot.setLegendOrientation("SOUTH");
}
else
new_figure = true; // if figures do not remain create one on next plot
} // close currentFigTableIndex
}
return currentFigSlotExamined+1; // return index of the closed figure
}
static public void setColor(int red, int green, int blue) {
Color newColor = new Color(red, green, blue);
currentPlot.setForeground(newColor);
currentPlot.setBackground(newColor);
currentPlot.repaint();
}
// var x = vrand(500); plot(x); markX(100, 200, new Font("Arial", Font.BOLD, 30)); markX(10.0, 0.3)
static public void xlabel(String xLabelStr) {
currentPlot.setAxisLabel(scalaSci.math.plot.PlotPanel.xAxisId, xLabelStr);
}
static public void ylabel(String yLabelStr) {
currentPlot.setAxisLabel(scalaSci.math.plot.PlotPanel.yAxisId, yLabelStr);
}
static public void zlabel(String zLabelStr) {
if (currentPlot instanceof Plot3DPanel)
currentPlot.setAxisLabel(scalaSci.math.plot.PlotPanel.zAxisId, zLabelStr);
}
// set the color for LaTex text and return the previous setting
public static Color setLatexColor(Color col) {
Color prevColor = PlotGlobals.latexColor;
PlotGlobals.latexColor = col;
return prevColor;
}
public static void latexLabel(String latex) {
texLabel txl = new scalaSci.math.plot.plotObjects.texLabel(latex, 1, 1);
currentPlot.addPlotable(txl);
}
public static void latexLabel(String latex, int coordx, int coordy) {
texLabel txl = new scalaSci.math.plot.plotObjects.texLabel(latex, coordx, coordy);
currentPlot.addPlotable(txl);
}
public static void latexLabel(String latex, int size, int coordx, int coordy) {
texLabel txl = new scalaSci.math.plot.plotObjects.texLabel(latex, size, coordx, coordy);
currentPlot.addPlotable(txl);
}
public static void latexLabel(String latex, double coordx, double coordy) {
texLabel txl = new scalaSci.math.plot.plotObjects.texLabel(latex, coordx, coordy);
currentPlot.addPlotable(txl);
}
public static void latexLabel(String latex, int size, double coordx, double coordy) {
texLabel txl = new scalaSci.math.plot.plotObjects.texLabel(latex, size, coordx, coordy);
currentPlot.addPlotable(txl);
}
public static void latexLabel3d(String latex, double nw1, double nw2, double nw3, double se1, double se2, double se3, double sw1, double sw2, double sw3) {
LatexImage tximg = new scalaSci.math.plot.plotObjects.LatexImage(latex, nw1, nw2, nw3, se1, se2, se3, sw1, sw2, sw3);
currentPlot.addPlotable(tximg);
}
public static void latexLabel3d(String latex, int xcoord, int ycoord) {
LatexImage tximg = new scalaSci.math.plot.plotObjects.LatexImage(latex, xcoord, ycoord);
currentPlot.addPlotable(tximg);
}
public static void latexRender(String latex) {
TeXFormula tf = new TeXFormula(latex);
TeXIcon icontf = tf.createTeXIcon(TeXConstants.STYLE_DISPLAY, 20);
icontf.setInsets(new Insets(5, 5, 5, 5));
OutputTextPane otp = new OutputTextPane();
otp.addIcon(icontf, 0, true);
JPanel jp = new JPanel();
jp.add(otp);
JFrame tstF = new JFrame("test");
tstF.add(jp);
tstF.setSize(200, 200);
tstF.setVisible(true);
}
/*
var t=inc(0, 0.01, 10); var x = sin(3.4*t); var y = sin(3.4*t); plot(t,x, y)
*/
/*
var t=inc(0, 0.01, 10); var x = sin(3.4*t); plot(t,x)
var latex = "\\int_{i=1}^{N} k_i"
latexLabel(latex, 50, 100, 100)
*/
}