Наложить линию на гистограмму в Gnuplot - PullRequest
2 голосов
/ 25 марта 2019

Я использую C ++ в Xcode на Mac и метод pipe для связи с Gnuplot.Я заинтересован в преобразовании моих массивов в графики непосредственно через программу после ее запуска.Используя

FILE *f = popen("gnuplot -persist", "w");

, я открываю файл и затем общаюсь с помощью fprintf.

Теперь у меня есть некоторые данные в представляющих интерес массивах.w - это «предложенный» массив стандартных нормальных переменных, и я намерен проверить, действительно ли это распределение Гаусса со средним значением = 0 и дисперсией = 1. Для этого я строю гистограмму.После этого я хочу наложить настоящую гауссову функцию, которая имеет ex в качестве значений координат оси и gauss в качестве значений координат y непосредственно на гистограмме.Как я могу это сделать?

Вот код на данный момент:

double start = -4; //min
double end = 4 ; //max
double numberofbins = 100;
double width = (end-start)/numberofbins ;

fprintf (f,
         "set ylabel '# of elements'\n"
         "set xlabel 'The numbers'\n"
         "Min = %g\n" //where binning starts
         "Max = %g\n" // where binning ends
         "n = %g\n" // the number of bins
         "width = 10**(-1)\n" // binwidth;  (Max-Min)/n
         "bin(x) = width*(floor((x-Min)/width)+0.5) + Min\n"
         "f(x)= e**((-x**2)/2) / sqrt(2*pi)\n"
         "plot '-' using (bin($1)):(1) smooth freq with boxes,'' u $2:$3 with lines linestyle 1\n",start,end,numberofbins)

for (int i= 0; i < numberofpoints; i++){
    fprintf(f, "%g %g %g\n", w[i], ex[i], gauss[i]);
}

fclose(f);

Вот результат, если я запускаю продемонстрированный код:

output 01

Как мы видим, биннинг прошел успешно, но строка была пропущена и выдает следующую ошибку:

gnuplot> plot '-' using (bin($1)):(1) smooth freq with boxes,'' u $2:$3 with lines linestyle 1
                                                               ^
     line 100000: column() called from invalid context

Я проверил онлайн, но никто не практикует такой способ общения с Gnuplot.

Если я строю только часть 2: 3 (без биннинга), я получаю этот график:

output 02

Таким образом, проблемаможет быть с совместимостью этих двух графиков.

Ответы [ 2 ]

2 голосов
/ 25 марта 2019

Существуют различные способы построения «встроенных» данных.

plot '-' u 1:2 w lines
1 11
2 22
3 33
e

Из gnuplot help special-filenames

Если вы используете и '-', и '' на одном графикекоманда, вам нужно иметь два набора встроенных данных, ...

Это означает:

plot '-' u 1:2 w boxes, '' u 1:2 w lines
1 11
2 22
3 33
e
1 11
2 22
3 33
e

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

$Data <<EOD
1 11
2 22
3 33
EOD

plot $Data u 1:2 w boxes, '' u 1:2 w lines
0 голосов
/ 31 марта 2019

Я решил проблему, создав вторую ось y на том же графике и построив ее в соответствии с ней. Используемый код был:

 fprintf (f,
             "set xlabel 'The numbers'\n"
             "Min = %g\n" //where binning starts
             "Max = %g\n" // where binning ends
             "n = %g\n" // the number of bins
             "width = 10**(-1)\n" // binwidth;  (Max-Min)/n
             "bin(x) = width*(floor((x-Min)/width)+0.5) + Min\n"
             "set ytics 100 nomirror tc lt 1\n"
             "set ylabel '# of elements' tc lt 1\n"
             "set y2tics 0.4 nomirror tc lt 2\n"
             "set y2label 'Theoretical Gaussian' tc lt 2\n"
             "plot '-' using (bin($1)):(1) smooth freq with boxes title 'Generator Histogram','-' u 1:2 with l axes x1y2 title 'Theoretical Gaussian (mean=0, std = 1)'\n",start,end,numberofbins) ;

    for (int i= 0; i < numberofpoints; i++){
        fprintf(f, "%g\n", w[i]);
    } 
    fprintf(f,"e\n");

    for (int i= 0; i < numberofpoints; i++){
        fprintf(f, "%g %g\n",ex[i], gauss[i]);
    }
    fprintf(f,"e\n");
    fclose(f);   

который строит это: enter image description here

...