web-dev-qa-db-ja.com

Cコードにグラフを自動的にプロットさせる

次に、gnuplotを使用してデータを個別にプロットすることを目的として、データのリストを「.dat」ファイルに書き込むプログラムを作成しました。私のコードにそれを自動的にプロットさせる方法はありますか?私の出力は次の形式です:

x-coord    analytic    approximation
x-coord    analytic    approximation
x-coord    analytic    approximation
x-coord    analytic    approximation
x-coord    analytic    approximation
 ....

理想的には、コードを実行すると、グラフもxラベル、yラベル、およびタイトル(Cコードから変更できる)で印刷されます。どうもありがとう。

17
JMzance

私はgnuplotに関して何か他のものを探している間にこれに出くわしました。古い質問ですが、サンプルコードをいくつか提供したいと思いました。私はこれを私のプログラムに使用していますが、かなりきちんとした仕事をしていると思います。私の知る限り、このPIPEingはUnixシステムでのみ機能します(Windowsユーザーについては、以下の編集を参照してください)。私のgnuplotインストールは、Ubuntuリポジトリからのデフォルトのインストールです。

_#include <stdlib.h>
#include <stdio.h>
#define NUM_POINTS 5
#define NUM_COMMANDS 2

int main()
{
    char * commandsForGnuplot[] = {"set title \"TITLEEEEE\"", "plot 'data.temp'"};
    double xvals[NUM_POINTS] = {1.0, 2.0, 3.0, 4.0, 5.0};
    double yvals[NUM_POINTS] = {5.0 ,3.0, 1.0, 3.0, 5.0};
    FILE * temp = fopen("data.temp", "w");
    /*Opens an interface that one can use to send commands as if they were typing into the
     *     gnuplot command line.  "The -persistent" keeps the plot open even after your
     *     C program terminates.
     */
    FILE * gnuplotPipe = popen ("gnuplot -persistent", "w");
    int i;
    for (i=0; i < NUM_POINTS; i++)
    {
    fprintf(temp, "%lf %lf \n", xvals[i], yvals[i]); //Write the data to a temporary file
    }

    for (i=0; i < NUM_COMMANDS; i++)
    {
    fprintf(gnuplotPipe, "%s \n", commandsForGnuplot[i]); //Send commands to gnuplot one by one.
    }
    return 0;
}
_

[〜#〜]編集[〜#〜]

私のアプリケーションでは、呼び出しプログラムを閉じるまでプロットが表示されないという問題にも遭遇しました。これを回避するには、fprintfを使用して最後のコマンドを送信した後にfflush(gnuplotPipe)を追加します。

また、Windowsユーザーがpopenの代わりに__popen_を使用する場合があることも確認しました。ただし、Windowsがインストールされていないため、これを確認できません。

編集2

Gnuplotに_plot '-'_コマンドを送信し、続いてデータポイントと文字 "e"を送信することで、ファイルへの書き込みを回避できます。

例えば.

_fprintf(gnuplotPipe, "plot '-' \n");
int i;

for (int i = 0; i < NUM_POINTS; i++)
{
  fprintf(gnuplotPipe, "%lf %lf\n", xvals[i], yvals[i]);
}

fprintf(gnuplotPipe, "e");
_
42
BenB

Gnuplotスクリプトを作成してgnuplotを実行するプロセスを起動し、コマンドラインからこのスクリプトをプロットするか、提供されているインターフェースの1つを使用できます。 Cの場合、Nicolas DevillardからのPOSIXパイプベースのインターフェースがここにあります: http://ndevilla.free.fr/gnuplot/ ...そしてiostreamベースのC++バージョンはgitから入手できます(参照: http://www.stahlke.org/dan/gnuplot-iostream/

ただし、最も移植性が高く、おそらく最も簡単な方法は、gnuplotを呼び出してスクリプトをプロットすることです。 sje397で述べたように、stdlib.hのsystem()呼び出しのドキュメントを確認してください。

補足として、GNU plotutilsもあります。これは、アプリケーションで使用できる、データセットをプロットするためのライブラリであるlibplotを提供します。以下を参照してください。 http://www.gnu .org/software/plotutils /

5
Jim Brissom

これを行う方法はたくさんありますが、最も簡単な方法は、Cでsystem()(stdlib.hから)関数を使用することです。最初にgnuplotスクリプトを作成し、「name。 gp "(名前も拡張子も重要ではありません)。
簡単なスクリプトは、

_plot 'Output.dat' with lines
_

このスクリプトファイルを保存したら、次を追加します
system("gnuplot -p name.gp");
コードの最後に。
それはそれと同じくらい簡単です。

Windowsシステムパス変数にgnuplotパスを追加してください。

2

一時ファイルの使用を避けながら、フロート配列をプロットするために受け入れられた回答を採用しました。初期化、 float* data_は配列であり、size_t size_ その大きさ。うまくいけば、それは誰かのために役立ちます!

乾杯、
アンドレス

void plot(const char* name="FloatSignal"){
  // open persistent gnuplot window
  FILE* gnuplot_pipe = popen ("gnuplot -persistent", "w");
  // basic settings
  fprintf(gnuplot_pipe, "set title '%s'\n", name);
  // fill it with data
  fprintf(gnuplot_pipe, "plot '-'\n");
  for(size_t i=0; i<size_; ++i){
    fprintf(gnuplot_pipe, "%zu %f\n", i, data_[i]);
  }
  fprintf(gnuplot_pipe, "e\n");
  // refresh can probably be omitted
  fprintf(gnuplot_pipe, "refresh\n");
}