Home > Programming > Using PHP and R to create SVG Graphs for Web

Using PHP and R to create SVG Graphs for Web

You can use the statistical package R to create sophisticated, data-driven SVG graphics for browser applications, particularly when you can choose the browser the client is working on.

Since R wants to write a file to the file system, create a named pipe in php and pass that value to the R script, and call R from the command line (your install location may vary):

<?php
/**
 * r_example
 *
 * program calls R script, and displays output to web.
 *
 */
//to get graphics output from R, we need to create a temporary named pipe.

//create random temp file name
$pipeFile = "/tmp/R-" . mt_rand() . ".svg";
posix_mkfifo($pipeFile, 0600);

//open the pipe for reading, so R has something to write to
$svgPipe = fopen($pipeFile, 'r+');
//stream_set_blocking($svgPipe, TRUE);

$output = shell_exec("/usr/bin/R -f svg.R --args " . $pipeFile);
$xmlTextFromR = "";

//read the pipe, and add it to a variable
while($input = trim(fgets($svgPipe))) {
	stream_set_blocking($svgPipe, FALSE);
	$xmlTextFromR = $xmlTextFromR . $input;
}

//close the pipe
if(file_exists($pipeFile)) {
	if(!unlink($pipeFile)) {
		die("unable to remove pipe");
	}
}

In R, we are going to simply take the name for the pipe, and write an svg graph to the pipe.

# svg.R
# creates a simple graph and exports to the file passed as the first argument
# Author: sgrizzard
###############################################################################
# send errors to stdout
sink(type="message")
args = commandArgs(TRUE) #Read user-specific arguments
args[1]

# open svg library
library(RSvgDevice)
args[1] = gsub('^[[:space:]]+', '', args[1]) #remove space
devSVG(args[1])
cars <- c(1, 3, 6, 4, 9)
plot(cars)
dev.off()

q()

Back in PHP, we now have the XML in a text variable, which we can simply echo to the browser.  Or, we can load that XML into a DOM object, and manipulate it.

$xmlFromR = DOMDocument::loadXML($xmlTextFromR);
if ($xmlFromR == FALSE) {
	throw new Exception('error loading xml from buffer');
}

//add some text at the top of the svg object to show off
$titleTextNode = $xmlFromR->createElement("text", "some text");
$titleTextNode->setAttribute("style", "font-size:10");
$titleTextNode->setAttribute("transform", "translate(10, 10)");
$svgParentNode = $xmlFromR->getElementsByTagName("svg")->item(0);

$svgParentNode->appendChild($titleTextNode);

//send svg content header, and output the svg to the browser.
header('Content-Type: image/svg+xml;charset=UTF-8');
echo $xmlFromR->saveXML();

?>

Since we used the RSvgDevice package in the R script, we need to install it.  Start R as the web user (or root), and run:

install.packages("RSvgDevice", repos="http://cran.stat.ucla.edu/")

If all goes well, you should see the following in your web browser:

 

Categories: Programming Tags:
  1. No comments yet.
  1. No trackbacks yet.