爪車

C言語でgnuplotを利用してグラフ表示

最近、C言語のプログラム中からgnuplotを呼び出し、グラフの表示をする方法を知りました。
パイプを使ってgnuplotにコマンドを送る方法です。特別なライブラリ等を使用するわけではないので気楽に利用できます。

こちらのページを参考にさせて頂きました。
4 C言語からgnuplotを操作する

いままでは、Cプログラムで計算したデータをファイルに書き出して、エクセルやらgnuplotなどでグラフ表示処理していましたが、プログラム中でグラフを処理できるようになるのでかなり便利です。
プログラムの実効中に逐一データをグラフ処理できるので、リアルタイムでグラフを表示したりできます。
工夫すればグラフのアニメーション表示もできます。

試しに
1.sin(x)をプロット
2.配列のデータを曲線と点で同じグラフに重ねてプロット
3.三次元プロットのアニメーション表示
するプログラムを作成してみました。

以下のプログラムはLinux環境下で実効できます。
あらかじめgnuplotのインストールが必要です。
Windows環境で動かす時は
工学ナビの中の人の研究と周辺 C言語のプログラムでgnuplotにグラフを描かせる(Windows)
を参考にしてください。

// test1.c sin(x)をプロット
#include <stdio.h>

int main(void)
{
FILE *gp;

gp = popen("gnuplot -persist", "w"); // パイプを開き、gnuplotの立ち上げ

fprintf(gp, "plot sin(x)\n"); // パイプを通してgnuplotにコマンドを送る

fprintf(gp, "exit\n"); // gnuplotの終了
fflush(gp);
pclose(gp); // パイプを閉じる

return 0;
}

Screenshot-Gnuplot-test1.gif


// test2.c 配列のデータを曲線と点でプロット
#include <stdio.h>
#include <math.h>
#define N 100

int main(void) {
FILE *gp;

int i;
double x[N], y1[N], y2[N];

// データ生成
for (i = 0; i < N; ++i) {
x[i] = M_PI/18*i;
y1[i] = sin(x[i]);
y2[i] = cos(x[i]);
}

gp = popen("gnuplot -persist", "w"); // パイプを開き、gnuplotの立ち上げ
fprintf(gp, "set multiplot\n"); // マルチプロットモード
fprintf(gp, "set xrange [%f:%f]\n", x[0], x[N-1]); // 範囲の指定
fprintf(gp, "set yrange [-1.2:1.2]\n");
fprintf(gp, "set xlabel \"x\"\n"); // ラベル表示
fprintf(gp, "set ylabel \"y\"\n");

// 曲線のプロット
fprintf(gp, "plot '-' with lines linetype 1\n");
for (i = 0; i < N; ++i) {
fprintf(gp, "%f\t%f\n", x[i], y1[i]);
}
fprintf(gp, "e\n");

// 点のプロット
fprintf(gp, "plot '-' with points pointtype 1\n");
for (i = 0; i < N; ++i) {
fprintf(gp, "%f\t%f\n", x[i], y2[i]);
}
fprintf(gp, "e\n");

fprintf(gp, "set nomultiplot\n"); // マルチプロットモード終了
fprintf(gp, "exit\n"); // gnuplotの終了
fflush(gp);
pclose( gp); // パイプを閉じる

return 0;
}

Screenshot-Gnuplot-test2.gif


// test3.c 三次元プロットのアニメーション表示
#include <stdio.h>
#include <math.h>
#include <unistd.h>
#define N 100

int main(void) {
FILE *gp;

int i;
int j;
double x, y, z, t;

gp = popen("gnuplot -persist", "w"); // パイプを開き、gnuplotの立ち上げ
fprintf(gp, "set xrange [-1.2:1.2]\n"); // 範囲の指定
fprintf(gp, "set yrange [-1.2:1.2]\n");
fprintf(gp, "set zrange [0:10]\n");
fprintf(gp, "set xlabel \"x\"\n"); // ラベル表示
fprintf(gp, "set ylabel \"y\"\n");
fprintf(gp, "set zlabel \"z\"\n");

// 三次元プロットのアニメーション表示
for (j = 0; j < N; ++j) {
usleep(50000); // usec待機
fprintf(gp, "splot '-' with lines linetype 1\n");
for (i = 0; i < N; ++i) {
t = 0.2*i;
x = cos(t+0.1*j);
y = sin(t+0.1*j);
z = t;
fprintf(gp, "%f\t%f\t%f\n", x, y, z);
}
fprintf(gp, "e\n");
}

fprintf(gp, "exit\n"); // gnuplotの終了
fflush(gp);
pclose(gp); // パイプを閉じる

return 0;
}

Screenshot-Gnuplot-test3.gif


パイプを通す方法だと、gnuplotだけでなく、OctaveやScilabもCプログラム中から利用できます。

« ヒト型ロボット 35 両脚支持期間の導入 |Top|ODEの導入メモ »

コメント

コメントの投稿

管理者にだけ表示を許可する

トラックバック

http://tsumeguruma.blog46.fc2.com/tb.php/92-d05dedd9

Top

HOME

tsumehashi

Author:tsumehashi
FC2ブログへようこそ!

10 | 2017/11 | 12
- - - 1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 - -