Живой график для приложения на 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`
Другие вопросы по тегам