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;
}

// 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;
}

// 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;
}

パイプを通す方法だと、gnuplotだけでなく、OctaveやScilabもCプログラム中から利用できます。
パイプを使って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;
}

// 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;
}

// 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;
}

パイプを通す方法だと、gnuplotだけでなく、Octaveや
コメント
コメントの投稿
トラックバック
http://tsumeguruma.blog46.fc2.com/tb.php/92-d05dedd9