## Thursday, June 2, 2011

### Plotting Graph

This article presents a step by step tutorial to implement a simple graph plotting program.

Step 1 : Data Sampling
There are two sources of data, the first one is the real world data such as stock price.
The second one is from a mathematical equation, for example, we may plot a graph for the equation

```y=x2
```

If we limit x in the range of 0 to 6, we would take 7 sample points and have the following sequence of data :
```x={0,1,2,3,4,5,6}
y={0,1,4,9,16,25,36}
```

Since the data is evenly spaced along the x-dimension, we can ignore the x sequence and just focused on the y sequence. To input the sequence to our program, we prepare a data file known as data.txt. The file can be created using any text editor. The data file contains 7 rows with one data value in each row.

Contents of data.txt as follows :
```0
1
4
9
16
25
36
```

Step 2 : read the data
Once the data is ready, we must read it from the data file into our program. The data will be stored in a double[] array. File reading is done by the API in the BufferedReader class.

Step 3 : scaling
Suppose we are plotting a graph in a panel with size 600x300 pixels. To evenly distribute the 7 data points along the x direction, the gap between every data point will be 100 pixels. That is, the x-coordinates in pixels will be (0,100,200,300,400,500,600).
In this case, the scaling factor will be 100, which can be calculated from the following formula :

```xScale = PANEL_WIDTH/(NUMBER_OF_DATA_POINT-1)
= 600 / (7-1)
= 600 / 6
= 100
```

The scaling factor in the y-dimension can be calculated as

```yScale = PANEL_HEIGHT/(MAX_DATA-MIN_DATA)
= 300 / (36-0)
= 8.333
```

Step 4 : Ploting the data point
We will use a red circle to plot the data point. This can be done by the fillOval API

Step 5 : Connecting the data points
Just use the drawLine() API will do.

Full Source Code

```/******************************************************************************
* File : Visualizer.java
* Author : http://java.macteki.com/
* Description :
*   Visualize a sequence of data by ploting a graph just like the MS excel.
* Requirement : data.txt which contains the sequence of data.
* Tested with : JDK 1.6
******************************************************************************/

class Visualizer extends javax.swing.JPanel
{
double[] data=null;
double minData=1e308, maxData=-1e308;

void readData() throws Exception
{
String filename="data.txt";

// count number of lines
int count=0;
String line="";
br.close();

double[] a=new double[count];
this.data=a;

// re-open the file

// read data line by line and store them in an array
count=0;
{
double y=Double.parseDouble(line);
a[count++]=y;
if (y<minData) minData=y;
if (y>maxData) maxData=y;
}

}

// this will be called automatically when the panel is displayed
public void paintComponent(java.awt.Graphics gr)
{
if (data==null) return;
gr.setColor(java.awt.Color.GRAY);
gr.fillRect(0,0,getWidth(),getHeight());

int width=getWidth();
int height=getHeight();
double xScale = (double) width/(double)(data.length-1);
double yScale = (double) height/(double) (maxData-minData);
double xp=-999,yp=0;  // previous point
for (int i=0;i<data.length;i++)
{
double x=i*xScale;
double y=(data[i]-minData)*yScale;
y=height-y;  // top-down transformation
gr.setColor(java.awt.Color.RED);
gr.fillOval((int)x-5,(int)y-5,10,10);
// connect previous point with current point
gr.setColor(java.awt.Color.BLUE);
if (xp!=-999) gr.drawLine((int)xp,(int)yp,(int)x,(int)y);
xp=x;  yp=y;
}
}

public static void main(String[] args) throws Exception
{
javax.swing.JFrame window=new javax.swing.JFrame();
window.setTitle("Macteki Data Visualizer");
window.setDefaultCloseOperation(javax.swing.JFrame.EXIT_ON_CLOSE);
Visualizer panel=new Visualizer();