Simple data plotting from a C console application using SVG

Synopsis:

  • Write a console application that processes some data.
  • Use the technique below to easily generate a graphical plot of your data using only standard C library functions (fopen, fprintf, fclose).
  • View the plot in an ordinary web browser.

A few months ago, I came across a lovely example showing how gnuplot can be used to output high quality data plots from console applications written in C. Since I love writing plain and simple console applications in C, this struck me as an incredibly useful idea. I’ve lost the link, but it was very like this other nice example that I’ve just found.

Anyway, I thought it would be interesting to apply the same principle to plotting data in an SVG image. Here’s a short example in C that stores a series of x-y data points (in this case, about one and a half cycles of a cosine wave) in two arrays, then plots the data as an SVG image straight into an HTML file that can then be opened directly in a web browser (or uploaded to a web server, I suppose). Not all browsers display SVG images, but nowadays I think most probably do.

Firstly, here’s what one of these plots actually looks like when viewed in a browser:

Screenshot of HTML file including SVG image viewed in a browser

Now, here’s the C code that produced the above image. The first half is mostly just generating some example data. The part that actually creates the output image is the second half, where all the fprintf statements are.

//
// svgplot.c - This program plots data to an HTML
// file as an SVG image
//
// Written by Ted Burke - last modified 22-11-2011
//

#include <stdio.h>

int main()
{
	// Create some data (a cosine wave)
	int n, N=100;
	double x[N], y[N], xmin, xmax, ymin, ymax;
	for (n=0 ; n<N ; ++n)
	{
		// Add data point
		x[n] = n/10.0;
		y[n] = cos(x[n]);

		// Find x and y limits
		if (n==0) {xmin = x[0]; xmax = x[0]; ymin = x[0]; ymax = x[0];}
		if (x[n] < xmin) xmin = x[n];
		if (x[n] > xmax) xmax = x[n];
		if (y[n] < ymin) ymin = y[n];
		if (y[n] > ymax) ymax = y[n];
	}

	// Some general properties of the plot
	char filename[] = "plot.html";
	int w=320, h=200; // pixel size on screen

	// Add a little empty space around the plot
	double left, right, top, bottom;
	left = xmin - 0.1*(xmax-xmin);
	right = xmax + 0.1*(xmax-xmin);
	bottom = ymin - 0.1*(ymax-ymin);
	top = ymax + 0.1*(ymax-ymin);

	// Begin SVG file
	FILE *f = fopen(filename, "w");
	fprintf(f, "<html><body><svg xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\"");
	fprintf(f, " width=\"%dpx\" height=\"%dpx\"", w, h);
	fprintf(f, " viewBox=\"%lf %lf %lf %lf\"", left, bottom, right-left, top-bottom);
	fprintf(f, " preserveAspectRatio=\"none\">\n");
	fprintf(f, "<g transform=\"scale(1.0 -1.0)\">\n\n");

	// Create axes
	fprintf(f, "<polyline points=\"%lf,%lf %lf,%lf\"", left, 0.0, right, 0.0);
	fprintf(f, " style=\"fill:none;stroke:grey;stroke-width:%lf\" />\n", (top-bottom)/h);
	fprintf(f, "<polyline points=\"%lf,%lf %lf,%lf\"", 0.0, bottom, 0.0, top);
	fprintf(f, " style=\"fill:none;stroke:grey;stroke-width:%lf\" />\n\n", (right-left)/w);

	// Plot data using a polyline element
	fprintf(f, "<polyline points=\"");
	for (n=0; n<N ; ++n) fprintf(f, "%lf,%lf ", x[n], y[n]);
	fprintf(f, "\" style=\"fill:none;stroke:black;stroke-width:%lf\" />", (right-left)/w);

	// Complete the HTML file
	fprintf(f, "\n\n</g></svg></body></html>\n");
	fclose(f);
}

Finally, this is the content of the HTML file. As you can see, it’s really just SVG wrapped in a couple of opening and closing HTML tags.

<html><body><svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="320px" height="200px" viewBox="-0.990000 -1.199662 11.880000 2.399632" preserveAspectRatio="none">
<g transform="scale(1.0 -1.0)">

<polyline points="-0.990000,0.000000 10.890000,0.000000" style="fill:none;stroke:grey;stroke-width:0.011998" />
<polyline points="0.000000,-1.199662 0.000000,1.199969" style="fill:none;stroke:grey;stroke-width:0.037125" />

<polyline points="0.000000,1.000000 0.100000,0.995004 0.200000,0.980067 0.300000,0.955336 0.400000,0.921061 0.500000,0.877583 0.600000,0.825336 0.700000,0.764842 0.800000,0.696707 0.900000,0.621610 1.000000,0.540302 1.100000,0.453596 1.200000,0.362358 1.300000,0.267499 1.400000,0.169967 1.500000,0.070737 1.600000,-0.029200 1.700000,-0.128844 1.800000,-0.227202 1.900000,-0.323290 2.000000,-0.416147 2.100000,-0.504846 2.200000,-0.588501 2.300000,-0.666276 2.400000,-0.737394 2.500000,-0.801144 2.600000,-0.856889 2.700000,-0.904072 2.800000,-0.942222 2.900000,-0.970958 3.000000,-0.989992 3.100000,-0.999135 3.200000,-0.998295 3.300000,-0.987480 3.400000,-0.966798 3.500000,-0.936457 3.600000,-0.896758 3.700000,-0.848100 3.800000,-0.790968 3.900000,-0.725932 4.000000,-0.653644 4.100000,-0.574824 4.200000,-0.490261 4.300000,-0.400799 4.400000,-0.307333 4.500000,-0.210796 4.600000,-0.112153 4.700000,-0.012389 4.800000,0.087499 4.900000,0.186512 5.000000,0.283662 5.100000,0.377978 5.200000,0.468517 5.300000,0.554374 5.400000,0.634693 5.500000,0.708670 5.600000,0.775566 5.700000,0.834713 5.800000,0.885520 5.900000,0.927478 6.000000,0.960170 6.100000,0.983268 6.200000,0.996542 6.300000,0.999859 6.400000,0.993185 6.500000,0.976588 6.600000,0.950233 6.700000,0.914383 6.800000,0.869397 6.900000,0.815725 7.000000,0.753902 7.100000,0.684547 7.200000,0.608351 7.300000,0.526078 7.400000,0.438547 7.500000,0.346635 7.600000,0.251260 7.700000,0.153374 7.800000,0.053955 7.900000,-0.046002 8.000000,-0.145500 8.100000,-0.243544 8.200000,-0.339155 8.300000,-0.431377 8.400000,-0.519289 8.500000,-0.602012 8.600000,-0.678720 8.700000,-0.748647 8.800000,-0.811093 8.900000,-0.865435 9.000000,-0.911130 9.100000,-0.947722 9.200000,-0.974844 9.300000,-0.992225 9.400000,-0.999693 9.500000,-0.997172 9.600000,-0.984688 9.700000,-0.962365 9.800000,-0.930426 9.900000,-0.889191 " style="fill:none;stroke:black;stroke-width:0.037125" />

</g></svg></body></html>
This entry was posted in Uncategorized and tagged , , , , , , , . Bookmark the permalink.

One Response to Simple data plotting from a C console application using SVG

  1. carlos says:

    hello, looking for information on the internet svg find your page
    I saw the other post in your blog and your implementations of others works on C and i think you are a C guru.

    I’m doing something about graphs in C and I wonder if you can help me to implement this function:

    char * grafica_genera_svg (struct graph * a, func_a_cadena f);

    to create a graph in SVG.

    Actually not quite understand svg and not as would be generated to implement the function graph, please I hope you can help me you would saving my life, of advance thank you very much
    carlos.28pedraza@gmail.com

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s