Jack
Jack

Reputation: 753

Write to a textfile and plot with c++ and gnuplot

I'm quite a novice on C++, I am trying to write the output of my script to a text-file and plot the output using gnuplot. Here is the script:

#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <fftw3.h>
#include <iostream>
#include <cmath>
#include <fstream>
using namespace std;

int main(void)
{
    int i;
    double y;
    int N=256;
    double Fs=30000;//sampling frequency
    double  T=1/Fs;//sample time 
    double f=5000;//frequency
    double *in;
    fftw_complex *out;
    double t[N-1];//time vector 
    fftw_plan plan_forward;



    in = (double*) fftw_malloc(sizeof(double) * N);
    out = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * N);


    for (int i=0; i< N;i++)
    {
        t[i]=i*T;
        in[i] =0.7 *sin(2*M_PI*f*t[i]);// generate sine waveform
        double multiplier = 0.5 * (1 - cos(2*M_PI*i/(N-1)));//Hanning Window
       in[i] = multiplier * in[i];
      }

    plan_forward = fftw_plan_dft_r2c_1d ( N, in, out, FFTW_ESTIMATE );

    fftw_execute ( plan_forward );

    for ( i = 0; i < N; i++ )
    {
    printf ( "  %4d  %12f\n", i, in[i] );
    }

fftw_destroy_plan ( plan_forward );
fftw_free ( in );
fftw_free ( out );
return 0;
}

So the outputs are i and in[i]

As the first attmept to write my output to a text file I have added this code to my script inside the main function:

fstream myfile;

myfile.open ("example.txt");

  for(i = 0; i < N; ++i)

    { myfile << i << std::endl;

      myfile << in[i] << std::endl;
    }

myfile.close();

I could not get i and in[i] in two columns besides each other so I have typed

./Nameofthefile >stdout.txt 2>stderr.txt

in the terminal and now I have have i and in[i] in two columns side by side in my stdout.txt file something like this:

 1      0.000092

 2      0.000368

and so on. When I type

gnuplot "stdout.txt"

in the terminal I get this error:

0      0.000000
^
"stdout.txt", line 1: invalid command

I have two questions:

1-How to fix this error

2- How to put i and in[i] in two columns side by side in my "example.txt". The way I see it in "stdout.txt". Thanks.

Upvotes: 1

Views: 3176

Answers (2)

Galik
Galik

Reputation: 48635

Some of your header files are not recommended for C++. To use the C++ versions of the former C standard library headers you can specify the name prefixed with c and without the .h extension.

So these:

#include <stdlib.h>
#include <stdio.h>
#include <time.h>

would become:

#include <cstdlib>
#include <cstdio>
#include <ctime>

Your problem is that you are not providing everything gnuplot needs to draw a graph. You are supplying the raw data but no instructions on what to do with the data.

You need to output a file something like this:

plot '-' using 1:2
1 0.000092
2 0.000368

So you can add the plot command in your original program like this:

printf("plot '-' using 1:2\n"); // add this
for(i = 0; i < N; i++)
{
    printf("%4d  %12f\n", i, in[i]);
}

Or in your other example like this:

std::fstream myfile;

myfile.open("example.txt");

myfile << "plot '-' using 1:2" << std::endl;
for(i = 0; i < N; ++i)
{
    myfile << i << " " << in[i] << std::endl;
}

myfile.close();

You can plot the output file using:

gnuplot -p < "stdcout.txt"

Upvotes: 2

ex-bart
ex-bart

Reputation: 1392

You've created a data file for gnuplot. However, gnuplot expects a script in its own language, which may then use the plot command (or similar commands) to actually generate plots of data files. Read the gnuplot documentation.

To get two columns, just insert a space between them:

myfile << i << " " << in[i] << std::endl;

You can also use a tab "\t", which will probably lead to a nicer display when you view the file, but gnuplot does not care which one you use.

Upvotes: 1

Related Questions