gnuplotを使用してC言語からパイプを使って計算結果を表示する方法

このQ&Aのポイント
  • LinuxでC言語からパイプを使ってgnuplotに接続し、計算した結果を表示しようとする際、グラフの表示に時間がかかる場合の解決策を教えてください。
  • gnuplotにパイプで接続し、1000回のループ内でグラフを表示する際、表示に時間がかかる現象が発生しています。対策方法を教えてください。
  • LinuxでC言語からgnuplotにパイプを使って計算結果を表示しようとしていますが、グラフの表示に時間がかかる問題があります。解決策を教えてください。
回答を見る
  • ベストアンサー

gnuplotについて質問です。

現在、linuxでC言語からパイプを使ってgnuplotに接続し、計算した結果をすぐに表示しようとしています。 下のようなプログラムでうまくいくと思ったのですが、グラフが表示されるのにすごい時間がかかってしまいます。 解決策をご存知でしたらご教示お願いいたします。 #include<stdio.h> #include<stdlib.h> #include<math.h> void main(){ FILE *plotin; double x , y; int i = 0; struct sched_param param; struct timespec tt; //gnuplotにパイプで接続 plotin = popen("gnuplot","w"); //制御LOOP開始 for(i = 0 ; i < 1000 ; i ++) { if( i == 10000) { exit(0); } //gnuplotで表示するグラフの計算 x = i * 0.01; y = x*x; //gnuplotに表示する fprintf(plotin,"plot '-' title \"oscillation\" \n"); fprintf(plotin,"%f %f\n", x,y); fprintf(plotin,"e\n"); i++; } //gnuplot閉じる pclose(plotin); }

質問者が選んだベストアンサー

  • ベストアンサー
回答No.3

意味がわかりました 次の二つを試してください 1、ループの外に出したfprintfをもどす 2、ループ内の最後にfflush(plotin);を追加する

その他の回答 (2)

  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.2

このようなプログラムでのデバグのこつは、いきなりパイプを使うのではなく plotin = popen("gnuplot","w"); を plotin = fopen("debug.txt","w"); としてファイルの出力したり plotin = stdout; として標準出力に出力したりして、その内容が意図したものになっているかどうか確認することです。 ちなみに、私なら実運用でもpopenを使わず、標準出力のままコマンドラインでgnuplotにパイプで渡しますが。 ○このプログラムは「1組の(x,y)の点」というグラフを「(ループ回数)枚作図」するものになっています。これは意図したものなのでしょうか?「(ループ回数)組の(x,y)の点」というグラフを「1枚作図」ではないでしょうか。 後者なら fprintf(plotin,"plot '-' title \"oscillation\" \n"); for(略 { (略) fprintf(plotin,"%f %f\n", x,y); } fprintf(plotin,"e\n"); という流れになります。 ○ループカウンタとして使っている変数iですが > if( i == 10000){exit(0);} とループ回数から有り得ない判定があったり > i++; とfor以外のところで加算してたりしてます。この意図はなんでしょう? 提示したプログラムは完全なものですか? 省略したところは無いですか? 省略したところで変数iを使ってたりしませんか?そのためにループ回数がおかしくなっているとかは無いですか? struct sched_param param; struct timespec tt; と、定義されていない構造体があるので、省略した部分がある、と予想されるのですが。 あとは今回のとは関係ないですが ○このプログラムだと、最後のグラフを表示した次の瞬間、gnuplotが終了しますので、おそらく、グラフ表示したウィンドウが閉じます。set terminalを適切なものに設定するとか pause -1 で一時停止させるとかが必要です。 ○ main関数はint型にしましょう。

simizukiyo
質問者

補足

回答ありがとうございました。 申し訳ありません。 本来のプログラムは余計な情報が色々含まれていたので、質問用に荒削りしたものを乗せた所、色々と不具合のあるプログラムになってました。 お二方からご指摘いただいた部分を修正したプログラムを下記に添付します。 このプログラムを実行した結果、先にxとyの計算を10000回行い、計算が終了した後にグラフが生成されました。 この結果を元に新たに2つ質問させてください。 1:やりたい事としては、計算をしながらリアルタイムにgnuplotに点をプロットさせたいです。 (将来的にセンサから取得した値を逐一グラフで表示しながら確認したいため) 計算しながら表示というのは出来ないのでしょうか。 2:計算終了後からgnuplotの計算までに数秒の時間がかかります。 これは私のPCの性能のせいなのか、gnuplotの性能なのか、プログラムの書き方が間違っているのか、いったい何が原因なのでしょうか。 (一応PCを再起動して、無駄なプログラム等を終了してから試してみましたが結果は変わりませんでした。) もしお時間がありましたらご教授お願いいたします。 #include<stdio.h> #include<stdlib.h> #include<math.h> int main(void){ FILE *plotin; double x , y; int i = 0; //gnuplotにパイプで接続 plotin = popen("gnuplot -persist","w"); fprintf(plotin,"plot '-' title \"oscillation\" \n"); //制御LOOP開始 for(i = 0 ; i < 10000 ; i ++) { //gnuplotで表示するグラフの計算 x = i * 0.01; y = x*x; //gnuplotに表示する fprintf(plotin,"%f %f\n", x,y); } fprintf(plotin,"e\n"); //gnuplot閉じる pclose(plotin); return 0; }

回答No.1

forループから、一個目と三個目のfprintfを外に出せばいいと思うよ と言うかこれじゃグラフ出なくない?

関連するQ&A

  • gnuplotでreplotできない??

    下記のプログラムを書きました。 下記のプログラムでは1枚のグラフの複数のグラフをどんどん重ね、さらに1つのemfファイルとして出力し保存しようとしています。 しかし、問題が発生しました。 プログラム中のfprintf(gp, "replot (x+1)*x*(x-1)\n");を消すとプログラムは動くのですがreplotがあるとうまく画像ファイルが保存されません。 emfファイルはできている(ファイル容量は0ではない。)のですが、emfファイルが壊れており見ることができません。 その理由がわかる方がいましたら、教えていただけないでしょうか? よろしくお願いします。 以下、書いたプログラムです。 #include <stdio.h> #include <windows.h> #include <tchar.h> #include <string> #include<conio.h> using namespace std; #define GNUPLOT_PATH "C:/gnuplot/gnuplot/binary/gnuplot.exe" //char *a[10]; char a[10][50]; long n; long l; int main() { FILE *gp; gp = _popen(GNUPLOT_PATH, "w"); if (gp == NULL) { fprintf(stderr, "Oops, I can't find %s.", GNUPLOT_PATH); exit(EXIT_FAILURE); } // gnuplotにコマンドを送る fprintf(gp, "set terminal emf color 'Ryumin-Light-EUC-H' 16\n"); fprintf(gp, "set output '%s.emf'\n", a[n]); fprintf(gp, "set title '日本語-入力テスト'\n"); //x軸の範囲の設定 //fprintf(gp, "set xrange [-60:60]\n"); //fprintf(gp, "set yrange [0:3]\n"); fprintf(gp, "set grid\n"); fprintf(gp, "set datafile separator ','\n"); fprintf(gp, "set datafile separator ','\n"); fprintf(gp, "set key bottom outside\n"); fprintf(gp, "plot sin(x)\n");     fprintf(gp, "replot (x+1)*x*(x-1)\n"); fflush(gp); // バッファに格納されているデータを吐き出す(必須) //getchar(); // 入力待ち _pclose(gp); exit(EXIT_SUCCESS); return 0; }

  • C言語からgnuplot呼び出し

    C言語からgnuplotを呼び出したいのですが、一瞬表示されてすぐ消えてしまいます。 プログラムは以下のように書きました。 --------------------------------------------------------------- #include <stdio.h> #include <stdlib.h> #include <math.h> int main(int argc, char **argv) { FILE *gid; int i; double x; gid=popen("gnuplot -persist","w"); for (i=0; i<100 ;i++){ x = 0.03*i; fprintf(gid,"plot sin(x-%f*pi)\n",x); } pclose(gid); } --------------------------------------------------------------- この後、 gcc test.c -lm ./a.out でコンパイル、実行しました。 かなり初心者なので初歩的な質問かもしれませんがよろしくお願いします。

  • gnuplotの出力グラフ名を外部で書き換えたい

    LINUX上のCからgnuplotを用い、適当なデータを作成し、グラフを1枚作成することに成功しました。今後はループ処理によって、データ名とグラフ名を替えながら大量のデータ処理をするつもりです。 gnuplotに送りこむデータ名の変更の仕方、グラフ名の変更の仕方を教えてください。 'out.data','out.png'を書き換える方法です。例えば’out1.data'から'out1000.data'。'out1.png'から'out1000data'のようにできれば、1000個のデータを処理し1000枚のグラフを作成できます。 下記に適当なグラフを出力するプログラム例を示します。 #include <stdio.h> #include <stdlib.h> #include <math.h> int main(void){ FILE *data, *gp char *data_file; int i; double x,y; //make data file data_file="out.data"; data = fopen(data_file,"w"); for(i=0;i<=5;i++){ x=i; x=i*i; fprintf(data,"%f\t%f\n",x,y); } fclose(data); //make graph gp=popen("gnuplot -persist","w"); fprintf(gp,"set terminal png\n"); fprintf(gp,"set xrange [0:5]\n"); fprintf(gp,"set yrange [0:50]\n") fprintf(gp,"set output 'out.png'\n"); fprintf(gp,"plot \"%s\"with lines linetype 1 \n", data_file); pclose(gp); return(gp); return 0; }

  • gnuplot で2本のグラフを一つにまとめる

    表示したいデータ X   Y1    Y2 2.000  3.0   -86.10 2.167  15.0   -90.64 2.333  21.0   -87.25 2.500   6.0    -84.04 表示するプログラム #include <stdio.h> #include <stdlib.h> #include <math.h> #include <string.h> char output_file[128]; int main(void){ sprintf(output_file,"./output.txt"); FILE *gp = popen("gnuplot -persist","w"); fprintf(gp, "set terminal png\n"); fprintf(gp, "set xrange [1:3]\n"); fprintf(gp, "set xtics 1,1,3\n"); fprintf(gp, "set mxtics 6\n"); fprintf(gp, "set xlabel 'Hour'\n"); fprintf(gp, "set yrange [0:50]\n"); fprintf(gp, "set ytics 0,5,50\n"); fprintf(gp, "set ylabel 'mm/h'\n"); fprintf(gp, "set y2range [-90:-75]\n"); fprintf(gp, "set y2tics -90,5,-75\n"); fprintf(gp, "set ytics nomirror\n"); fprintf(gp, "set my2tics 5\n"); fprintf(gp, "set y2label 'dbm'\n"); fprintf(gp, "set output './output.png'\n"); fprintf(gp, "set title 'Rain and Attenuation'\n"); fprintf(gp, "plot './output.txt' using 1:2 with lines linetype 1 ,'./output.txt' using 1:3"); } 左横軸は0から50までとなりました。 右横軸はー90からー80までとなりました。 XvsY1の曲線は左横軸に対応して正しく表示されました。 ただし、XvsY2の曲線は表示されませんでした。 解決法を教えてください。

  • C言語によるgnuplotの呼び出し

    シミュレーションによって得られた計算結果を自動的にgnuplotで 表示させるプログラミングを作成しました。シミュレーション自体は fortranで行っていてfort.61というファイルが出力されます。 c言語でこのファイルを読みとって、それに少し細工をしfort.62 というファイルに新たに書き込んで、gnuplotで表示させたいのですが、 gnuplotの画面で no valid dataというエラーが表示されてしまいます。 ところが、cのプログラムを終了させてからgnuplotでこのfort.62を 通常の方法でplotすると、きちんとグラフが表示されます。 何が原因がわかるかたいらっしゃいましたら、教えて下さい。 ちなみにコンパイルはcygwin上でgccを使用しています。以下にソース を添付します。gnuplotで読み込んでいるファイルplot.pltは 「plot "fort.62"」と記述してあるtextファイルです。 よろしくお願いします。 #include <stdio.h> #include <stdlib.h> #include <math.h> int main(void) {     FILE *fp,*fp2;     int i,N;     double x,y;     double volt[100],curr[100];     double norm,para;     para = 0.2442E-03;     N=14;     fp=fopen("fort.61","r");     for(i=0;i<N;i++){       fscanf(fp,"%lf %lf",&x,&y);       volt[i] = x;       curr[i] = y;       if(volt[i] == -1.0){       norm = para/curr[i];       }     }     for(i=0;i<N;i++){       curr[i] = norm*curr[i];     }   close(fp);   fp2 = fopen("fort.62","w");     for(i=0;i<N;i++){       fprintf(fp2,"%lf %lf\n",volt[i],curr[i]);     }     close(fp2);     system("wgnuplot -persist plot.plt"); }

  • C言語における漢字の取り扱いについて??

    C言語とgnuplotを利用して下記のプログラムを書きました。 #include<iostream> #include<cstdio> #include<stdio.h> using namespace std; #define GNUPLOT_PATH "C:/gnuplot/gnuplot/binary/gnuplot.exe" int main() { FILE *gp; char s[100]; scanf("%s", s); gp = _popen(GNUPLOT_PATH, "w"); if (gp == NULL) { fprintf(stderr, "Oops, I can't find %s.", GNUPLOT_PATH); exit(EXIT_FAILURE); } // gnuplotにコマンドを送る fprintf(gp, "set terminal png\n"); fprintf(gp, "set output 'plot_sample.png'\n"); //fprintf(gp, "set "xl 距離"\n"); fprintf(gp, "set title '%s'", s); fprintf(gp, "set xrange [-pi:pi]\n"); fprintf(gp, "plot sin(x), (x+1)*x*(x-1)\n"); fflush(gp); // バッファに格納されているデータを吐き出す(必須) //getchar(); // 入力待ち _pclose(gp); exit(EXIT_SUCCESS); } ここでscanf(%s,s);のところでsに、あア亜と入力しました。 最終的にpngの画像としてあア亜と出力させようとしているのですが、文字化けして文字がうまくひょうじされていません。 なぜ、うまくいかないのかわかっていません。 pngにおける文字の取り扱いの問題なのかC言語における文字の取り扱いなのかと考えて解決策を考えているのですが、うまくいきません。 もしわかる方がいましたら教えていただけないでしょうか? よろしくお願いいたします。

  • gnuplotをC言語で操作する方法

    C言語を用いてgnuplotを操作しデータファイルから自動的にグラフを作成するプログラムを作ろうとしています。 使用環境はWindows7、VisualStudio2010です。 ほとんどの部分はうまくいったのですが一部分が正しく表示されません。 軸の目盛ラベルの表示フォーマット設定のコマンドで set format x "%.1f" として小数点以下一桁を強制的に表示させるためC言語でパイプを用いて #define GNUPLOT_PATH "C:/gnuplot/binary/pgnuplot.exe" int plot(char *file_name){ FILE *gp; gp = _popen(GNUPLOT_PATH, "w"); fprintf(gp, "set title 'TEST PLOT'\n"); : (中略) : fprintf(gp, "set format x '%.1f' \n");//この部分が正しく反映されません。 : (中略) : fprintf(gp, "plot '%s' using 1:2 with linespoints lt 4 lw 5 pt 6 ps 2.0 lc rgb 'red'\n",file_name); fprintf(gp,"quit \n"); fflush(gp); _pclose(gp); return 0; } '%.2f' の部分をいろいろいじってみたのですがうまくいかず、なぜできないのか原因がわかりません。 fprintf()の数値代入の %f と混ざってしまっているのでしょうか?

  • gnuplotで

    gnuplotで 例えば x = 10 のグラフを書きたいのですがどのようにしたら良いかわかりません。 例えば、y = 2x+10 であれば、 plot 2*x + 10 で書くことができますが、 y軸に垂直な値を記入する方法をご存知の方教えて下さい。

  • gnuplotでのグラフ作成について

    タイトルに在るとおりgnuplotを使用してのグラフ作成について質問させていただきます。 作成したいグラフの数式は、 z=h(x,y) h(x,y)=1/1+√<x^4+y^4> ×{xsin(4√<x^4+y^4>)+ycos(√<x^4+y^4>)} ただし、 x と y の範囲は -3 から 3 まで というものです。こういった形で数式を書くことに慣れていないため、見づらいところ多々在るでしょうが、ご容赦ください。 恥ずかしながらgnuplotというソフトに触れることが初めてなため、検索などを利用して自分なりに調べた結果なのですが。 1 h(x,y)=~ で h の数式を設定。 2 set xrange[-3:3] 3 set yrange[-3:3] で x y の範囲を指定。 4 sprot h(x,y) でグラフを作成する という流れになるのではないか、ということがなんとなくですがわかりました。 ここで私は、x yの範囲を指定後、h をプロットしようとするところで、hの情報が不足している(?)とのメッセージにて弾かれてしまいます。 恐らく私の、h の数式入力に不備が在るのだろうと思います。 平方根をsqrt 乗数は**n になることはわかっているのですが、どうにも手詰まりです。 お力添えをいただけないでしょうか。よろしくお願いします。

  • gnuplotの使いかた(linux)

    gnuplotを用いて3次元のグラフを描こうとしています。 試しに、 set pm3d splot exp(-x*x)*exp(-y*y) というコマンドを実行すると、 Error:terminal "unknown" does not support continuous colors. が表示されます。 使用OSは linux debian gnome terminal です。 gnuplot version4.0です。 どうすれば、3次元のグラフを描くことができるのでしょうか?

専門家に質問してみよう