Живой график для приложения на C
У меня есть приложение, которое периодически входит в систему хоста, это может быть файл или консоль. Я хотел бы использовать эти данные для построения статистического графика для меня. Я не уверен, что смогу использовать живой график для своего приложения.
Если этот инструмент правильный, могу ли я привести пример интеграции внешнего приложения с живым графом?
это прямая ссылка на ссылку -> http://www.live-graph.org/download.html
2 ответа
Я думаю, что это может быть достигнуто проще всего с помощью Python плюс matplotlib. Чтобы достичь этого, на самом деле есть несколько способов: а) интегрировать интерпретатор Python непосредственно в приложение C, б) распечатать данные в стандартный вывод и передать их в простой скрипт на языке Python, который выполняет фактическое построение графиков. Далее я опишу оба подхода.
У нас есть следующее приложение C (например, plot.c
). Он использует интерпретатор Python для взаимодействия с функциями построения графиков в matplotlib. Приложение может отображать данные напрямую (при вызове ./plot --plot-data
) и распечатать данные в stdout
(когда вызывается с любым другим установленным аргументом).
#include <Python.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#define CMD_BUF_SIZE 256
void initializePlotting() {
Py_Initialize();
// load matplotlib for plotting
PyRun_SimpleString("from matplotlib import pyplot as pp");
PyRun_SimpleString("pp.ion()"); // use pp.draw() instead of pp.show()
}
void uninitializePlotting() {
Py_Finalize();
}
void plotPoint2d(double x, double y) {
// this buffer will be used later to handle the commands to python
static char command[CMD_BUF_SIZE];
snprintf(command, CMD_BUF_SIZE, "pp.plot([%f],[%f],'r.')\npp.draw()", x, y);
PyRun_SimpleString(command);
}
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 < 1000; i++) {
double x = myRandom(), y = myRandom();
if (plot) plotPoint2d(x,y);
else printf("%f %f\n", x, y);
}
if (plot) uninitializePlotting();
return 0;
}
Вы можете построить это так:
$ gcc plot.c -I /usr/include/python2.7 -l python2.7 -o plot
И запустить его как:
$ ./plot --plot-data
Затем он некоторое время будет рисовать красные точки на оси.
Если вы решили не наносить данные напрямую, а распечатать их на stdout
Вы можете выполнять построение с помощью внешней программы (например, сценарий Python с именем plot.py
), который принимает данные от stdin
то есть канал, и выводит данные, которые он получает. Чтобы добиться этого, позвоните в программу, как ./plot | python plot.py
, с plot.py
быть похожим на:
from matplotlib import pyplot as pp
pp.ion()
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
pp.plot([x],[y],'r.')
pp.draw()
Я проверил оба подхода на моей машине Debian. Требуются пакеты python2.7
а также python-matplotlib
быть установленным.
РЕДАКТИРОВАТЬ
Я только что видел, что вы хотели построить гистограмму или что-то подобное, это, конечно, также возможно с помощью matplotlib, например, гистограммы:
from matplotlib import pyplot as pp
pp.ion()
values = list()
while True:
data = [float(x) for x in raw_input().split()]
values.append(data[0])
pp.clf()
pp.hist([values])
pp.draw()
Что ж, вам нужно всего лишь записать свои данные в заданном формате livegraph и настроить livegraph, чтобы построить то, что вы хотите. Если написал небольшой пример C, который генерирует случайные числа и сбрасывает их вместе со временем каждую секунду. Далее вы просто прикрепляете программу livegraph к файлу. Вот и все.
Играя с LiveGraph, я должен сказать, что его использование довольно ограничено. Я все еще придерживался бы скрипта на python с matplotlib, так как у вас есть намного больший контроль над тем, как и что отображается.
#include <stdio.h>
#include <time.h>
#include <unistd.h>
#include <gsl/gsl_rng.h>
#include <gsl/gsl_randist.h>
int main(int argc, char** argv)
{
FILE *f;
gsl_rng *r = NULL;
const gsl_rng_type *T;
int seed = 31456;
double rndnum;
T = gsl_rng_ranlxs2;
r = gsl_rng_alloc(T);
gsl_rng_set(r, seed);
time_t t;
t = time(NULL);
f = fopen("test.lgdat", "a");
fprintf(f, "##;##\n");
fprintf(f,"@LiveGraph test file.\n");
fprintf(f,"Time;Dataset number\n");
for(;;){
rndnum = gsl_ran_gaussian(r, 1);
fprintf(f,"%f;%f\n", (double)t, rndnum);
sleep(1);
fflush(f);
t = time(NULL);
}
gsl_rng_free(r);
return 0;
}
компилировать с
gcc -Wall main.c `gsl-config --cflags --libs`