X/Y Plot is a simple PHP chart class for making X/Y graphs. It includes fetches such as mean average and linnear regression.
X/Y Plot requires PHP 5.0 or above, since the code is entirely object-oriented. PHP must be compiled with GD graphic library (which is pretty hard to not have included anyway).
The hope is that this graphing library will be easy enough to understand that someone having no prior experense can it working within minutes.
I wrote this library after trying to find a simple PHP graphing library with linear regression. Having found nothing free and already put together, I just decided to write a library myself. This isn't the first time I've written a graphing library for a project and I decided to make it a nice object-oriented setup. Once it was complete, I decided to explore phpDocumentor and release this library to the public. So here it is. This is my first attempt at creating an auto-documented set of code, so I hope it turns out useful. - AAQ
MD5: 432aa7c74cf769b83ec3bb45cbe42539
SHA1: 6bff6e0464a4541c2d5d1c70f1ae155a03d9e012
MD5: 95578420c3ad503c7a98ced06c4f87b0
SHA1: 1e17aa3870ff8584c6909286516db3ac025490d6
Documentation is availibal online, generated by phpDocumentor.
This software is free, open-source software released under the GNU license.
X/Y Plot is written and maintained by Andrew Que. To get in touch with Andrew Que, visit his contact page
| 1 comment has been made | |
|
From Andrew Que (http://www.DrQue.net) Beloit, WI January 3rd, 2008 at 3:34AM
|
<?php
// Include the X/Y Plot library
require_once( 'RootDirectory.inc.php' );
require_once( $RootDirectory . "Includes/XY_Plot/XY_Plot.php" );
//-----------------------------------------------------------
$ImageWidth = 500;
$ImageHeight = 350;
//-----------------------------------------------------------
// Create image
$Image = @imagecreate( $ImageWidth , $ImageHeight )
or die( "Cannot Initialize new GD image stream" );
//---------------------------------
// Create basic color map
//---------------------------------
$ColorMap = array();
$ColorMap[ "Background" ] = imagecolorallocate( $Image , 255 , 255 , 255 );
imagecolortransparent( $Image , $ColorMap[ "Background" ] );
// Create a standard color palette
$ColorMap[ "Black" ] = imagecolorallocate( $Image , 0 , 0 , 0 );
$ColorMap[ "Red" ] = imagecolorallocate( $Image , 192 , 0 , 0 );
$ColorMap[ "Green" ] = imagecolorallocate( $Image , 0 , 192 , 0 );
$ColorMap[ "Blue" ] = imagecolorallocate( $Image , 0 , 0 , 192 );
$ColorMap[ "Brown" ] = imagecolorallocate( $Image , 48 , 48 , 0 );
$ColorMap[ "Cyan" ] = imagecolorallocate( $Image , 0 , 192 , 192 );
$ColorMap[ "Purple" ] = imagecolorallocate( $Image , 192 , 0 , 192 );
$ColorMap[ "LightGray" ] = imagecolorallocate( $Image , 192 , 192 , 192 );
$ColorMap[ "DarkGray" ] = imagecolorallocate( $Image , 48 , 48 , 48 );
$ColorMap[ "LightRed" ] = imagecolorallocate( $Image , 255 , 0 , 0 );
$ColorMap[ "LightGreen" ] = imagecolorallocate( $Image , 0 , 255 , 0 );
$ColorMap[ "LightBlue" ] = imagecolorallocate( $Image , 0 , 0 , 255 );
$ColorMap[ "Yellow" ] = imagecolorallocate( $Image , 255 , 255 , 0 );
$ColorMap[ "LightCyan" ] = imagecolorallocate( $Image , 0 , 255 , 255 );
$ColorMap[ "LightPurple" ] = imagecolorallocate( $Image , 255 , 0 , 255 );
$ColorMap[ "White" ] = imagecolorallocate( $Image , 255 , 255 , 255 );
// New plot
$XY_Plot = new XY_PlotClass( $Image );
?>
1 The typical location for X/Y Plot is in Includes/XY_Plot. The file RootDirectory.inc.php should be in the path that requests the script. This file is simply a path to the root directory of the web site reletive to the current path.
<?php
$RootDirectory = "./";
?>
1 This is a convention the author uses, but if it doesn't suit your tastes, simply modify the PHP files XY_Plot.php and ClipLine.php with your prefered system.
Rendering a data set with points. Each data point is add with the function AddData. This function takes two paremters: the X and Y location of a data point.
Before data can be rendered to a chart, a few basic parameters need to be set. The color of the points to be drawn which is done through the function SetColor. The span of the data must also be set with the functions SetX_Span and SetY_Span.
<?php
// Draw borders (define externally)
DrawBorders( 0 , 0 , 0 , 0 );
// New plot
$XY_Plot = new XY_PlotClass( $Image );
// Set plot colors
$XY_Plot->SetColor( $ColorMap[ "LightRed" ] );
// Set point size
$XY_Plot->SetCircleSize( 8 );
// Setup timeframe
$XY_Plot->SetX_Span( 0 , 150 );
$XY_Plot->SetY_Span( 0 , 10 );
// Add some data
$XY_Plot->AddData( 0 , 0 ); $XY_Plot->AddData( 86 , 5 );
$XY_Plot->AddData( 31 , 1 ); $XY_Plot->AddData( 11 , 6 );
$XY_Plot->AddData( 44 , 2 ); $XY_Plot->AddData( 50 , 7 );
$XY_Plot->AddData( 11 , 3 ); $XY_Plot->AddData( 83 , 8 );
$XY_Plot->AddData( 82 , 4 ); $XY_Plot->AddData( 136 , 9 );
// Render the points to image
$XY_Plot->RenderPoints();
// Output image
header( "Content-Type: image/png" );
ImagePNG( $Image );
?>
1 Rendering a data set with lines between the points
<?php
// ...
// Set plot colors
$XY_Plot->SetColor( $ColorMap[ "LightRed" ] );
// Add some data
$XY_Plot->AddData( 0 , 0 );
// ...
// Render the lines to image
$XY_Plot->RenderWithLines();
// Output image
header( "Content-Type: image/png" );
ImagePNG( $Image );
?>
1 Rendering with points and lines is as simple as calling both rendering functions. This is true of all rendering function. Remember order of operation--that is, the first rendered plot will end up on the bottom with subsiquint plots over the top.
<?php
// ...
// Render the points and lines to image
$XY_Plot->RenderWithLines();
$XY_Plot->RenderPoints();
// Output image
header( "Content-Type: image/png" );
ImagePNG( $Image );
?>
1 Rendering a data set with points and linear regression. The only extra step here is setting the linear regression color using the function SetLinearRegressionColor and then rendering this plot with RenderLinearRegression.
<?php
// ...
// Set linear regression color
$XY_Plot->SetLinearRegressionColor( $ColorMap[ "LightPurple" ] );
// Add some data
$XY_Plot->AddData( 0 , 0 );
$XY_Plot->AddData( 31 , 1 );
// ...
// Render the points and lines to image
$XY_Plot->RenderWithLines();
$XY_Plot->RenderPoints();
$XY_Plot->RenderLinearRegression();
// Output image
header( "Content-Type: image/png" );
ImagePNG( $Image );
?>
1 Rendering a data set with mean average. The only extra step here is setting the mean average color using the function SetAverageColor and then rendering this plot with RenderMeanPlot.
<?php
// ...
// Set linear regression color
$XY_Plot->SetAverageColor( $ColorMap[ "LightPurple" ] );
// Render the points and lines to image
$XY_Plot->RenderWithLines();
$XY_Plot->RenderPoints();
$XY_Plot->RenderMeanPlot();
// Output image
header( "Content-Type: image/png" );
ImagePNG( $Image );
?>
1 A chat doesn't have to take up the entire window. In fact, leaving margin space is needed if you are to put in lables or a ledgend.
The function SizeWindow is designed to setup the area in which the chart occupies in an image.
<?php
// Margins
$TopMargin = 10;
$BottomMargin = 10;
$LeftMargin = 10;
$RightMargin = 100;
// Draw borders (define externally)
DrawBorders(
$LeftMargin , $TopMargin ,
$RightMargin , $BottomMargin );
// New plot
$XY_Plot = new XY_PlotClass( $Image );
// Setup boundries
$XY_Plot->SizeWindow(
$LeftMargin , $TopMargin ,
$ImageWidth - $RightMargin , $ImageHeight - $BottomMargin );
// ...
// Render the points and lines to image
$XY_Plot->RenderWithLines();
$XY_Plot->RenderPoints();
$XY_Plot->RenderMeanPlot();
$XY_Plot->RenderLinearRegression();
// Output image
header( "Content-Type: image/png" );
ImagePNG( $Image );
?>
1 For this example, multiple charts have been placed on a single image. This is a standard application of such a function--plotting the data followed by the first and second derivative of the data on a single image.
To draw multiple charts on a single image, two additional steps are needed. The first image is drawn as excepted, using SizeWindow to place the data in the correct location. After this, ResetData is called to flush the data in the plot. Then, the window can be repositioned, new data added to the chart and the chart rendered to the image.
<?php
$LeftMargin = 10;
$RightMargin = 10;
$TopMargin = 10;
$BottomMargin = 70;
$TopMargin2 = 115;
$BottomMargin2 = 40;
$TopMargin3 = 145;
$BottomMargin3 = 10;
// New plot
$XY_Plot = new XY_PlotClass( $Image );
// Setup boundries
$XY_Plot->SizeWindow(
$LeftMargin , $TopMargin ,
$ImageWidth - $RightMargin , $ImageHeight - $BottomMargin );
// ... Add data ...
// Render the points and lines to image
$XY_Plot->RenderLinearRegression();
$XY_Plot->RenderWithLines();
$XY_Plot->RenderPoints();
// Draw borders (define externally)
DrawBorders(
$LeftMargin , $TopMargin2 ,
$RightMargin , $BottomMargin2 );
// Setup boundries
$XY_Plot->SizeWindow(
$LeftMargin , $TopMargin2 ,
$ImageWidth - $RightMargin , $ImageHeight - $BottomMargin2 );
$XY_Plot->ResetData();
// ... Add data ...
$XY_Plot->AutoScaleY_MinMax( 1.0 );
$XY_Plot->RenderMeanPlot();
$XY_Plot->RenderWithLines();
$XY_Plot->ResetData();
// ... Add data ...
// Draw borders (define externally)
DrawBorders(
$LeftMargin , $TopMargin3 ,
$RightMargin , $BottomMargin3 );
// Setup boundries
$XY_Plot->SizeWindow(
$LeftMargin , $TopMargin3 ,
$ImageWidth - $RightMargin , $ImageHeight - $BottomMargin3 );
$XY_Plot->AdjustMinMax( 1.0 );
$XY_Plot->RenderMeanPlot();
$XY_Plot->RenderWithLines();
// Output image
header( "Content-Type: image/png" );
ImagePNG( $Image );
?>
1 Veticle auto scaling can be complished using AutoScaleY_MinMax. This function will find the min and max Y values and scale the graph accordingly. AdjustMinMax has one parameter, which is a rounding value. This can be described as "round to the nearest". For example, if the largest Y-value is 23 and the lowest 10 and the rounded value set to 10, the min will be 10 and max is 30. If the rounded value is 25, the min will be 0 and the max 25.
In this chart, 4 plots of the same data are made but with different vertical scales. On the top left, the chart is scaled with no rounding. Since the minimum value is -21 and the maximum 136, these values are at the edge. The charts are all labled on intervals of 50. Thus, this chart has no lables on the top or bottom, since those do not fall on even intervals.
The chart on the top right is auto scaled to the nearest 25. The the maximum value of 136 is therefore rounded up to 150 and the minimum value of -21 is rounded down to -25. The divisions are again labled on intervals of 50. So the lowest interval is not labled, since the chart begins at -25. The highest interval is 150, which does get labled.
The chart on the bottom left is a more ideal setup. The auto scale is set to the nearest 50. This is idial because the the labled intervals are also in increments of 50. Thus, the chart is labled evenly from top the bottom.
The chart on the bottom right has an auto scale set to the nearest 100. This leaves empty divisions above and below the chart, which may be desired in some situations (such as if linear regression) extends into these areas.
<?php
// ...
// Setup timeframe
$XY_Plot->SetX_Span( 0 , 10 );
// Setup divisions
$XY_Plot->SetY_MajorDivisionScale( 50 );
$XY_Plot->SetY_MajorDivisionColor( $ColorMap[ "LightGray" ] );
$XY_Plot->SetY_MajorDivisionTextColor( $ColorMap[ "Black" ] );
// Graph 1
Draw(
0.0 ,
$LeftMargin1 , $TopMargin1 ,
$RightMargin1 , $BottomMargin1 );
// Graph 2
Draw(
25.0 ,
$LeftMargin2 , $TopMargin2 ,
$RightMargin2 , $BottomMargin2 );
// Graph 3
Draw(
50.0 ,
$LeftMargin3 , $TopMargin3 ,
$RightMargin3 , $BottomMargin3 );
// Graph 4
Draw(
100.0 ,
$LeftMargin4 , $TopMargin4 ,
$RightMargin4 , $BottomMargin4 );
// Output image
header( "Content-Type: image/png" );
ImagePNG( $Image );
//---------------------------------------------------------------------------
// Draw graph at given scale
//---------------------------------------------------------------------------
function Draw(
$Scale ,
$LeftMargin , $TopMargin ,
$RightMargin , $BottomMargin )
{
global $ImageWidth;
global $ImageHeight;
global $XY_Plot;
// Draw borders (define externally)
DrawBorders(
$LeftMargin , $TopMargin ,
$RightMargin , $BottomMargin );
// Setup boundries
$XY_Plot->SizeWindow(
$LeftMargin , $TopMargin ,
$ImageWidth - $RightMargin , $ImageHeight - $BottomMargin );
// Rescale
$XY_Plot->AutoScaleY_MinMax( $Scale );
// Draw divisions
$XY_Plot->DrawY_MajorDivisions();
// Render the points and lines to image
$XY_Plot->RenderWithLines();
$XY_Plot->RenderPoints();
}
?>
1 Sometimes the data for a chart will be missing chunks of data. Having a lines connect the points over the missing spans may not be desired. So the function SetMaxX_Distance defines a maximum seoerations in X values before leaving a gap between two points. This helps to visually represent the fact there is missing data.
<?php
// ...
// Add some data
$XY_Plot->AddData( 1 , 26 );
$XY_Plot->AddData( 2 , 59 );
$XY_Plot->AddData( 3 , 5 );
$XY_Plot->AddData( 4 , 8 );
$XY_Plot->AddData( 5 , 0 );
$XY_Plot->AddData( 6 , 27 );
$XY_Plot->AddData( 7 , 80 );
$XY_Plot->AddData( 8 , 50 );
$XY_Plot->AddData( 9 , 50 );
$XY_Plot->AddData( 10 , 134 );
$XY_Plot->AddData( 11 , 84 );
$XY_Plot->AddData( 12 , 123 );
$XY_Plot->AddData( 13 , 110 );
$XY_Plot->AddData( 14 , 158 );
$XY_Plot->AddData( 15 , 159 );
$XY_Plot->AddData( 16 , 122 );
$XY_Plot->AddData( 17 , 170 );
$XY_Plot->AddData( 18 , 139 );
$XY_Plot->AddData( 19 , 218 );
$XY_Plot->AddData( 20 , 208 );
$XY_Plot->AddData( 21 , 249 );
// Gap in data
$XY_Plot->AddData( 33 , 319 );
$XY_Plot->AddData( 34 , 382 );
$XY_Plot->AddData( 35 , 374 );
$XY_Plot->AddData( 36 , 378 );
$XY_Plot->AddData( 37 , 344 );
$XY_Plot->AddData( 38 , 354 );
$XY_Plot->AddData( 39 , 412 );
$XY_Plot->AddData( 40 , 442 );
$XY_Plot->AddData( 41 , 390 );
$XY_Plot->AddData( 42 , 465 );
$XY_Plot->AddData( 43 , 460 );
$XY_Plot->AddData( 44 , 488 );
$XY_Plot->AddData( 45 , 484 );
$XY_Plot->AddData( 46 , 476 );
$XY_Plot->AddData( 47 , 514 );
$XY_Plot->AddData( 48 , 522 );
// Auto scale
$XY_Plot->AdjustMinMax( 20 );
// Max distance of 10 units
$XY_Plot->SetMaxX_Distance( 10 );
// Render the points and lines to image
$XY_Plot->RenderLinearRegression();
$XY_Plot->RenderWithLines();
$XY_Plot->RenderPoints();
// Output image
header( "Content-Type: image/png" );
ImagePNG( $Image );
?>
1 There are four grides: vertical major, vertical minor, horizontal major and horizontal minor. The only difference between major and minor grides are that minor grids do not have an extention past the margin or lables.
Each of the major and minor grids have some common attributes: scale and color. The methods are as follows:
Major divisions have some additional functionality for lables. Division extentions, lable color, and lable text callbacks. Division extention is the term for the number of pixels past the right margin the line extends. This helps denote that the lable belongs to the line. The lable text callback is a function to format the lable. These will be explained latter.
This example shows how to setup a basic grid with lables. Major and minor grid lines are drawn.
View source codeIn this example, grids are dwarn with custom callback functions for both the verticle and horizontal scales. In addition, a custom increment function is used on the horizontal scale to increment the scale by months. The data for the horizontal scale is in seconds, and naturally, the seconds/month depends on the days in the month.
View source codeThis example shows the various statistics that can be generated from the data.
View source codeSeveral graphs can be drawn in the same chat area. This is done by simply calling ResetData and adding new data to be plotted. The one drawback is the chart must have it's scale pre-calculated.
View source codeThe graphing library has build into it clipping functions. Data that extends byond the margins is simply chopped off.
View source code(C) Copyright 2007 by Andrew Que