C言語のプログラムで,パイプを開いて,それをGnuplotに接続する方法を説明する。 これには次の方法が必要である。
1.パイプを開く
2.パイプを通してコマンドを送る
3.パイプを閉じる
1.パイプを開くためには,ファイルポインターをつかう. そのためファイルポインターを格納すの変数を用意しなくてはならない. パイプの先もファイルとして扱われるのである.
FILE *hoge;
2.Gnuplotを立ち上げて,そこにパイプを接続する必要がある. パイプの情報のファイルポインターで示される.
hoge = popen("gnuplot -persist","w");
popen()関数がパイプを開く命令であり、 これで Gnuplot が立ち上がり,パイプを通して,コマンドを送ることができる. またパイプを通して,Gnuplotにコマンドを送るのはfprintf()関数を使う.
fprintf(hoge, "plot sin(x)\n");
3.すべての動作が終了したならば,パイプを閉じなくてはならない. これはファイルの操作と全く同じである.
pclose(hoge);
例1.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main(int argc, char **argv)
{
FILE *gpid;
int i;
double x;
/* gnuplot を開く */
gpid = popen("gnuplot -persist","w");
/* gnuplot でグラフを書く */
for(i=1; i < 500; i++){
fprintf(gpid, "set xrange [0:4]\n");
fprintf(gpid, "set yrange [-1:1]\n");
x = 0.03*i;
fprintf(gpid,"plot sin(x- %f*pi)\n",x);
}
fprintf(gpid, "pause 10\n");
pclose(gpid);
return 0;
}
[出力結果]
例2.
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
FILE *gp;
int i;
double x;
//---Gnuplotを起動---
gp = popen("gnuplot -persist", "w");
//---座標の名前を入力---
fprintf(gp, "set xlabel \"x\"\n");
fprintf(gp, "set ylabel \"y\"\n");
for(i=1 ; i<=200 ; i++) {
x = 0.02 * i;
//---Gnuplotのコマンドを実行---
fprintf(gp, "plot sin(x-%f*pi)*cos(2*x-%f*pi)\n", x, x);
}
pclose(gp);
return (0);
}
[出力結果]
例3.
#include <stdio.h>
int main(void){
FILE *data, *gp;
int i, imax=20;
double x=-5.0, dx, y;
char *data_file;
/*------ データファイル作成 ---------- */
data_file="out.dat";
data = fopen(data_file,"w");
dx=10.0/imax;
for(i=0; i<=imax; i++){
if(x<-1){
y=-1.0;
}else{
y=1.0;
}
fprintf(data,"%f\t%f\n", x, y);
x+=dx;
}
fclose(data);
/*------ グラフの作成 ---------- */
gp = popen("gnuplot -persist","w");
fprintf(gp, "set xrange [-5:5]\n");
fprintf(gp, "set yrange [-1.5:1.5]\n");
fprintf(gp, "set pointsize 2\n");
fprintf(gp, "plot \"%s\" using 1:2 with linespoints 1 4 \n", data_file);
pclose(gp);
return 0;
}
[出力結果]
例4.
#include <stdio.h>
#include <math.h>
void mk_triangle_data(char *a, double x1, double x2, int n);
void mk_graph(char *f, char *xlb, double x1, double x2,
char *ylb, double y1, double y2);
/*==========================================================*/
/* main function */
/*==========================================================*/
int main(void){
double pi = 4*atan(1);
mk_triangle_data("out.txt", -2*pi, 2*pi, 1000);
mk_graph("out.txt", "x", -2*pi, 2*pi, "y", -3, 3);
return 0;
}
/*==========================================================*/
/* make a data file */
/*==========================================================*/
void mk_triangle_data(char *a, double x1, double x2, int n){
double x, dx;
double y1, y2, y3;
int i;
FILE *out;
dx = (x2-x1)/n;
out = fopen(a, "w");
for(i=0; i<=n; i++){
x = x1+dx*i;
y1 = sin(x);
y2 = cos(x);
y3 = tan(x);
fprintf(out, "%e\t%e\t%e\t%e\n", x, y1, y2, y3);
}
fclose(out);
}
/*==========================================================*/
/* make a graph */
/*==========================================================*/
void mk_graph(char *f, char *xlb, double x1, double x2,
char *ylb, double y1, double y2)
{
FILE *gp;
gp = popen("gnuplot -persist","w");
fprintf(gp, "reset\n");
/* ------- set x grid ---------*/
fprintf(gp, "set grid\n");
/* ------- set x axis ---------*/
fprintf(gp, "set xtics 1\n");
fprintf(gp, "set mxtics 10\n");
fprintf(gp, "set xlabel \"%s\"\n", xlb);
fprintf(gp, "set nologscale x\n");
fprintf(gp, "set xrange[%e:%e]\n", x1, x2);
/* ------- set y axis ---------*/
fprintf(gp, "set ytics 1\n");
fprintf(gp, "set mytics 10\n");
fprintf(gp, "set ylabel \"%s\"\n", ylb);
fprintf(gp, "set nologscale y\n");
fprintf(gp, "set yrange[%e:%e]\n", y1, y2);
/* ------- plat graphs ---------*/
fprintf(gp, "set terminal x11\n");
fprintf(gp, "plot \"%s\" using 1:2 with line,\
\"%s\" using 1:3 with line,\
\"%s\" using 1:4 with line\n", f, f, f);
fprintf(gp, "set terminal emf\n");
fprintf(gp, "set output \"tri.emf\"\n");
fprintf(gp, "replot\n");
pclose(gp);
}
[出力結果]
例5.
/*は熱方程式の近似解を陽解法により求めながら,GNUPLOT を用いて数値解を表示するプログラム*/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define dt 0.0005
#define N 10
#define T 1000
int main()
{
double u[N+1], new_u[N+1];
int i, j;
double dx = 1. / (float)N;
double r = dt / (dx * dx);
FILE *gpid;
/* gnuplot を開く */
if((gpid = popen("gnuplot -persist", "w")) == NULL) {
printf("I can't find gnuplot.\n");
exit(1);
}
/* y 方向の描画領域を固定 */
fprintf(gpid, "set yrange[-4:4]\n");
for(i = 0; i <= N; i++){
u[i] = 4 * cos(M_PI * i * dx);
}
for(j = 0; j < T; j++){
/* 熱方程式を陽解法で解く*/
for(i = 1; i < N; i++){
new_u[i] = r * u[i - 1] + (1. - 2. * r) * u[i] + r * u[i + 1];
}
new_u[0] = 2. * r * u[1] + (1. - 2. * r) * u[0];
new_u[N] = 2. * r * u[N - 1] + (1. - 2. * r) * u[N];
for(i = 0; i <= N; i++){
u[i] = new_u[i];
}
/* gnuplot でグラフを描く */
fprintf(gpid, "plot '-' w l t '%d'\n", j);
for(i = 0; i <= N; i++){
fprintf(gpid, "%lf %lf\n", i * dx, u[i]);
}
fprintf(gpid, "e\n");
fflush(gpid);
}
fprintf(gpid, "pause 10\n");
pclose(gpid);
return 0;
}
[出力結果]
例6.
/*==================================================*/
// 単振動シミュレーション (Euler Method)
/*==================================================*/
#include <stdio.h>
#include <math.h>
#define TIME 50 // 終了時刻
#define DT 0.01 // 時間刻み
// Gnuplotによるアニメーション
void plotter(FILE* gp, double t, double x);
/*==================================================*/
// 微分方程式 (d/dt)^2{x} = -x
// ↓
// d/dt{x} = +v
// d/dt{v} = -x
/*==================================================*/
double dxdt(double v) { return +v; }
double dvdt(double x) { return -x; }
int main(void)
{
int it;
double x = 0.0; // 初期位置
double v = 1.0; // 初期速度
double t = 0.0; // 現在時刻
int tmax = (int)ceil(TIME/DT); // ループ回数
FILE* gp = popen("gnuplot", "w");
for(it = 1; it <= tmax; it++) {
double x_old = x;
double v_old = v;
t = it*DT;
x = x + DT*dxdt(v_old);
v = v + DT*dvdt(x_old);
plotter(gp, t, x);
}
fprintf(stderr, "End. Hit Return Key\n");
getchar();
pclose(gp);
return 0;
}
void plotter(FILE* gp, double t, double x)
{
fprintf(gp, "set title 'Euler T = %4g'\n", t);
fprintf(gp, "set xrange[-5:5]\n");
fprintf(gp, "set yrange[-1:1]\n");
fprintf(gp, "plot '-' with points title 'Point'\n");
fprintf(gp, "%g, %g\n", x, 0.0);
fprintf(gp, "end\n");
fflush(gp);
}
[出力結果]
例7.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main(int argc, char **argv)
{
FILE *gid, *fid;
int i,j;
double x,y,z,t;
char *data={"test.dat"};
gid = popen("gnuplot","w");
fid = fopen(data,"w");
for (i=0; i<20; i++){
z = exp(0.05*i);
for(j=0; j<=36; j++){
x = z*cos(M_PI/18*j);
y = z*sin(M_PI/18*j);
fprintf(fid,"%f %f %f\n",x,y,z);
}
fprintf(fid,"\n");
}
fclose(fid);
fprintf(gid,"set hidden3d\n");
fprintf(gid,"set ticslevel 0\n");
for (i=0; i<=30 ;i++){
fprintf(gid, "set view %d,%d,,\n",30+2*i, i);
fprintf(gid, "splot '%s' w lines \n", data);
fflush(gid);
}
fprintf(gid,"pause 3\n");
pclose(gid);
}
[出力結果]
例8.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define DIV 71
#define INTERVAL 30
main(int argc, char **argv)
{
FILE *gid;
int i,j, gout;
double cmax, corr, EPS=1e-5, u[DIV][DIV];
double MESH=1.0/DIV;
if (argc>2) EPS = atof(argv[1]);
/* 境界条件*/
for (i = 0; i < DIV; i++){
for (j = 0; j < DIV; j++){
u[i][j]=0.0;
}
}
for (i = 0; i < DIV; i++) u[i][DIV-1]=1.0;
/* for (j = 0; j < DIV; j++) u[DIV-1][j]=1.0; */
#ifdef V38I
gid = popen("gnuplot","w");
fprintf(gid,"set pm3d\n");
fprintf(gid,"unset colorbox\n");
fprintf(gid,"set palette rgb 8,2,8\n");
fprintf(gid,"set size square\n");
#else
gid = popen("gnuplot","w");
fprintf(gid,"set size 0.7,1.1\n");
#endif
fprintf(gid,"set view 60,345\n");
fprintf(gid,"set xtics 0.2 \n");
fprintf(gid,"set ytics 0.2 \n");
fprintf(gid,"set ticslevel 0\n");
fprintf(gid,"set contour\n");
fprintf(gid,"set nokey\n");
fprintf(gid,"set size square\n");
/* Relaxation 法による反復解法*/
while(1) {
gout++;
cmax=0.0;
for (i = 1; i < DIV-1; i++){
for (j = 1; j < DIV-1; j++){
corr = (u[i+1][j]+u[i-1][j]+u[i][j+1]+u[i][j-1])/4.0 - u[i][j];
if ( fabs(corr) > cmax ) cmax = corr;
u[i][j] = u[i][j]+corr;
}
}
if ( cmax < EPS ) break;
if (gout % INTERVAL != 0) continue;
fprintf(gid,"splot '-' w lines"); /* 注目*/
for (i = 0; i < DIV; i+=2){
fprintf(gid,"\n");
for (j = 0; j < DIV; j+=2){
fprintf(gid,"%e %e %e\n",i*MESH,j*MESH,u[i][j]);
}
}
fprintf(gid,"e\n"); /* データ入力終了の印*/
}
/* 等高線の出力gnuplot にお任せ*/
fprintf(gid,"set cntrparam levels incre 0,0.05,1\n");
fprintf(gid,"set nosurface\n");
fprintf(gid,"set view 0,0\n");
fprintf(gid,"set noclabel\n");
fprintf(gid,"splot '-' w lines lt 2\n");
for (i = 0; i < DIV; i++){
fprintf(gid,"\n");
for (j = 0; j < DIV; j++){
fprintf(gid,"%e %e %e\n",i*MESH,j*MESH,u[i][j]);
}
}
fprintf(gid,"e\n");
fprintf(gid,"pause 60\n");
pclose(gid);
}
[出力結果]
例9.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main(int argc, char **argv)
{
FILE *gid;
int i,j;
double x;
gid = popen("gnuplot -geometry 512x384","w");
fprintf(gid, "set yrange[1:3]\n");
fprintf(gid, "set y2range[0:1]\n");
fprintf(gid, "set y2tics \n");
fprintf(gid, "set x2tics \n");
fprintf(gid, "set xtics nomirror\n");
fprintf(gid, "set ytics nomirror\n");
for (i=0; i<20; i++){
fprintf(gid, "plot '-' t 'Bottom-Left' w lines, \
'-' t 'Top-Right' axis x2y2\n");
for (j=0; j<100; j++){ /* 1番目のデータ*/
x = 0.02*j;
fprintf(gid,"%e %e\n",x,1+i*0.1/(1+x*x));
}
fprintf(gid,"e\n"); /* データ入力終了*/
for (j=0; j<100; j++){ /* 2番目のデータ*/
x = 0.01*j;
fprintf(gid,"%e %e\n", x, 1-exp(-(i*0.1)*x));
}
fprintf(gid,"e\n"); /* データ入力終了*/
}
fprintf(gid,"pause 60\n");
pclose(gid);
}
[出力結果]
例10. マトリックスデータの表示 その1
#include <stdio.h>
#define N_XPIXELS 3
#define N_YPIXELS 3
#define SLEEP 10000000
void write_data();
FILE *gp;
/* data: 3 x 3 */
int IMG[] = {
1,0,0,
0,1,1,
1,0,1,
};
int main (int argc, char *argv[] )
{
int i,j,k;
gp = popen("gnuplot -geometry 480x480","w");
fprintf(gp, "set pm3d\n");
fprintf(gp, "set view 0,0\n");
fprintf(gp, "unset key\n");
fprintf(gp, "splot '-' with pm3d\n");
write_data();
fprintf(gp,"e\n");
fflush(gp);
usleep(SLEEP);
fclose(gp);
}
/* write data for gnuplot */
void write_data(){
int i,x,y;
for (x=0; x<N_XPIXELS; x++){
for (y=0; y<N_YPIXELS; y++){
i = x + (N_YPIXELS -y -1)*N_XPIXELS;
fprintf(gp, "%d %d %d\n", x, y, IMG[i]);
fprintf(gp, "%d %d %d\n", x, y+1, IMG[i]);
}
fprintf(gp, "\n");
for (y=0; y<N_YPIXELS; y++){
i = x + (N_YPIXELS -y -1)*N_XPIXELS;
fprintf(gp, "%d %d %d\n", x+1, y, IMG[i]);
fprintf(gp, "%d %d %d\n", x+1, y+1, IMG[i]);
}
fprintf(gp, "\n");
}
}
[出力結果]
例10. マトリックスデータの表示 その2
#include <stdio.h>
#define N_XPIXELS 20
#define N_YPIXELS 20
#define SLEEP 10000000
void write_2d_data();
FILE *gp;
/* data: 20 x 20 */
int I[] = {
0,0,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0,1,0,
1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,
0,0,0,0,1,1,0,0,0,0,0,0,0,0,1,1,0,0,0,0,
0,1,1,0,1,1,0,1,1,0,0,0,0,0,1,1,0,0,0,0,
0,1,0,0,1,1,0,1,0,0,0,1,1,0,1,1,0,1,1,0,
1,0,1,0,1,1,0,1,1,0,0,1,1,0,1,1,1,1,1,1,
1,0,0,1,1,1,1,0,0,1,0,1,1,0,1,1,0,1,1,0,
0,0,0,0,1,1,0,0,0,0,0,1,1,0,1,1,0,1,1,0,
0,0,0,1,1,1,1,1,0,0,0,1,1,0,1,1,0,1,1,0,
0,0,1,0,1,1,0,0,1,1,0,1,1,0,1,1,0,1,1,0,
1,1,0,0,1,1,0,0,1,1,0,1,1,0,1,1,0,1,1,0,
0,0,0,1,0,0,0,1,0,0,0,1,1,1,1,1,1,1,1,0,
0,0,0,1,1,1,1,1,1,0,0,1,1,0,0,0,0,1,1,0,
0,0,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0,1,1,0,
0,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0,1,1,0,0,
1,0,0,1,0,1,0,0,0,0,0,0,0,0,1,1,1,1,0,0,
0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,1,0,0,0,
0,0,0,1,1,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,
0,0,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0
};
int main (int argc, char *argv[] )
{
int i,j,k;
gp = popen("gnuplot -geometry 480x480","w");
// fprintf(gp, "set term x11\n");
fprintf(gp, "set yrange [] reverse\n");
fprintf(gp, "unset key\n");
// fprintf(gp, "set out 'filename%d-%d.eps'\n",k,i);
fprintf(gp, "plot '-' matrix with image\n");
write_2d_data();
fprintf(gp,"e\n");
fprintf(gp,"e\n");
fflush(gp);
usleep(SLEEP);
fclose(gp);
}
/* write data for gnuplot */
void write_2d_data(){
int n_pixels = N_XPIXELS*N_YPIXELS;
int i;
for (i=0; i<n_pixels; i++){
fprintf(gp, "%d ", I[i]);
if ( (i+1)%N_XPIXELS == 0 ){
fprintf(gp, "\n");
}
}
}
[出力結果]
例10. マトリックスデータの表示 その3
#include <stdlib.h> /* drand48() */
#include <stdio.h>
#define N_XPIXELS 20
#define N_YPIXELS 20
#define RAND_SEED 20090503
#define SLEEP 100000000
void write_2d_data(unsigned char *img);
unsigned char *alloc_1d_uchar(int n);
FILE *gp;
int main (int argc, char *argv[] )
{
int i, n;
int nx, ny;
unsigned char *img;
long seed = RAND_SEED;
srand48(seed);
nx = N_XPIXELS;
ny = N_YPIXELS;
n = nx*ny;
img = alloc_1d_uchar(n);
for (i=0; i < n; i++){
img[i] = (unsigned char)(255.0*drand48());
}
gp = popen("gnuplot -geometry 480x480","w");
// gp = popen("gnuplot","w");
// fprintf(gp, "set terminal postscript eps color \"Times\" 20\n");
// fprintf(gp, "set terminal tgif\n");
// fprintf(gp, "set term x11\n");
fprintf(gp, "set yrange [] reverse\n");
fprintf(gp, "unset key\n");
// fprintf(gp, "set out 'image000.eps'\n");
// fprintf(gp, "set out 'image000.obj'\n");
fprintf(gp, "plot '-' matrix with image\n");
write_2d_data(img);
fprintf(gp,"e\n");
fprintf(gp,"e\n");
fflush(gp);
usleep(SLEEP); /* comment out when generate a file */
fclose(gp);
free(img);
}
/* write data for gnuplot */
void write_2d_data(unsigned char *img){
int n_pixels = N_XPIXELS*N_YPIXELS;
int i;
for (i=0; i<n_pixels; i++){
fprintf(gp, "%d ", img[i]);
if ( (i+1)%N_XPIXELS == 0 ){
fprintf(gp, "\n");
}
}
}
/*** Allocate 1d array of uchars ***/
unsigned char *alloc_1d_uchar(int n){
unsigned char *new;
new = (unsigned char *) malloc ((unsigned) (n * sizeof (char)));
if (new == NULL) {
printf("ALLOC_1D_CHAR: Couldn't allocate array of uchars\n");
return (NULL);
}
return (new);
}
[出力結果]
例11.2次元酔歩問題のシミュレーション
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <math.h>
#include <time.h>
#define L 512
main(int argc, char **argv)
{
int i, interval=100;
double x, y, S=sqrt(1.0/L);
FILE *GP;
if (argc == 2) interval = atoi(argv[1]);
srand48(time(NULL));
GP = popen("gnuplot -geometry 384x384","w");
fprintf(GP, "set xrange[-1:1]\n");
fprintf(GP, "set yrange[-1:1]\n");
fflush(GP);
sleep(1);
while(1){
fprintf(GP, "plot '-' with lines lt 1\n");
fflush(GP);
sleep(1);
x=0; y=0;
for (i = 0; i < L; i++){
fprintf( GP, "%f %f\n",
x += S*(drand48()-0.5), y += S*(drand48()-0.5) );
}
fprintf(GP,"e\n");
fflush(GP);
sleep(1);
}
fclose(GP);
}
[出力結果]
Back to C Language

