I think this can be achieved easiest using Python plus matplotlib. To achieve this there are actually multiple ways: a) integrating the Python Interpreter directly in your C application, b) printing the data to stdout and piping this to a simple python script that does the actual plotting. In the following I will describe both approaches.
We have the following C application (e.g. plot.c
). It uses the Python interpreter to interface with matplotlib's plotting functionality. The application is able to plot the data directly (when called like ./plot --plot-data
) and to print the data to stdout
(when called with any other argument set).
#include <Python.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
void initializePlotting() {
Py_Initialize();
// load matplotlib for plotting
PyRun_SimpleString(
"from matplotlib import pyplot as plt
"
"plt.ion()
"
"plt.show(block=False)
"
);
}
void uninitializePlotting() {
PyRun_SimpleString("plt.ioff()
plt.show()");
Py_Finalize();
}
void plotPoint2d(double x, double y) {
#define CMD_BUF_SIZE 256
static char command[CMD_BUF_SIZE];
snprintf(command, CMD_BUF_SIZE, "plt.plot([%f],[%f],'r.')", x, y);
PyRun_SimpleString(command);
PyRun_SimpleString("plt.gcf().canvas.flush_events()");
}
double myRandom() {
double sum = .0;
int count = 1e4;
int i;
for (i = 0; i < count; i++)
sum = sum + rand()/(double)RAND_MAX;
sum = sum/count;
return sum;
}
int main (int argc, const char** argv) {
bool plot = false;
if (argc == 2 && strcmp(argv[1], "--plot-data") == 0)
plot = true;
if (plot) initializePlotting();
// generate and plot the data
int i = 0;
for (i = 0; i < 100; i++) {
double x = myRandom(), y = myRandom();
if (plot) plotPoint2d(x,y);
else printf("%f %f
", x, y);
}
if (plot) uninitializePlotting();
return 0;
}
You can build it like this:
$ gcc plot.c -I /usr/include/python2.7 -l python2.7 -o plot
And run it like:
$ ./plot --plot-data
Then it will run for some time plotting red dots onto an axis.
When you choose not to plot the data directly but to print it to the stdout
you may do the plotting by an external program (e.g. a Python script named plot.py
) that takes input from stdin
, i.e. a pipe, and plots the data it gets.
To achieve this call the program like ./plot | python plot.py
, with plot.py
being similar to:
from matplotlib import pyplot as plt
plt.ion()
plt.show(block=False)
while True:
# read 2d data point from stdin
data = [float(x) for x in raw_input().split()]
assert len(data) == 2, "can only plot 2d data!"
x,y = data
# plot the data
plt.plot([x],[y],'r.')
plt.gcf().canvas.flush_events()
I have tested both approaches on my debian machine. It requires the packages python2.7
and python-matplotlib
to be installed.
EDIT
I have just seen, that you wanted to plot a bar plot or such thing, this of course is also possible using matplotlib, e.g. a histogram:
from matplotlib import pyplot as plt
plt.ion()
plt.show(block=False)
values = list()
while True:
data = [float(x) for x in raw_input().split()]
values.append(data[0])
plt.clf()
plt.hist([values])
plt.gcf().canvas.flush_events()