Живой график для приложения на C - PullRequest
6 голосов
/ 28 ноября 2011

У меня есть приложение, которое периодически входит в систему хоста, это может быть файл или консоль.Я хотел бы использовать эти данные для построения статистического графика для меня.Я не уверен, что смогу использовать живой график для своего приложения.

Если этот инструмент правильный, могу ли я привести пример интеграции внешнего приложения с живым графиком?

это прямая ссылка на ссылку -> http://www.live -graph.org / download.html

Ответы [ 2 ]

5 голосов
/ 30 ноября 2011

Я думаю, что это может быть достигнуто проще всего при использовании Python плюс matplotlib . Чтобы достичь этого, на самом деле есть несколько способов: а) интегрировать Python Interpreter непосредственно в ваше приложение на 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.

EDIT

Я только что видел, что вы хотели построить гистограмму или что-то подобное, это, конечно, также возможно с помощью 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()
1 голос
/ 29 ноября 2011

Что ж, вам нужно всего лишь записать свои данные в заданном формате живого графика и настроить прямой график для отображения того, что вы хотите.Если написал небольшой пример 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`
...