使用来自C程序的gnuplot绘制二进制3d数据

时间:2014-07-21 13:05:51

标签: 3d binary gnuplot

当我将数据存储为二进制文件时,我无法使用gnuplot绘制数据。从ASCII文件中绘制没有问题。这是我的尝试: 首先,保存数据

// omitted
double *t = alloc_mat(row + 1, col + 1);
    for(x = 0; x < row + 1; x++)
        for(y = 0; y < col + 1; y++)
            if(!y && !x)
                t[0] = col + 1;
            else if(!x && y != 0)
                t[x * (col + 1) + y] = y - 1;
            else if(!y && x != 0)
                t[x * (col + 1) + y] = x - 1;
            else
                t[x * (col + 1) + y] = data[(x - 1) * col + y - 1];

writebin_double(fname, t, row + 1, col + 1);
free(t);

代码创建了一个像

这样的结构
N+1, y0,  y1,  y2,  y3,  ...  yN
x0,  z00, z01, z02, z03, ..., z0N
x1,  y10, ...

根据http://gnuplot.sourceforge.net/docs_4.2/node330.html#binary_matrix

函数writebin_double就是

void writebin_double(char *fname, double *data, int row, int col)
{
    // omitted
    FILE *outfile = fopen(fname, "w");
    // omitted
    fwrite(data, sizeof(double), row * col, outfile);
    fclose(outfile);
}

尝试将数据绘制为

set xr [0:599] # an example
set yr [0:799]
splot 'plttmp.dat' binary matrix format='%double' using 1:2:3 w l palette t ''

它以“读取零宽度网格”失败,在这种情况下我不明白,因为在for循环中指定了网格。我也尝试了二进制通用设置,但它没有帮助,我得到了同样的信息。

感谢您的想法!

PS:Ubuntu 14.04上的gnuplot 4.6.4,64位

1 个答案:

答案 0 :(得分:1)

问题的解决方案:正如Christoph指出的那样,gnuplot只采用二进制格式的单精度浮点数。

但是,以这种格式绘制二进制数据仅适用于Ubuntu,而不适用于Windows。我的系统: Windows 7 64位,gnuplot 4.6.5 || Ubuntu 14.04 64 bit,gnuplot 4.6.4

以下是最低工作示例:

#include "stdio.h"
#include "stdlib.h"

typedef unsigned int uint;

void wdata_ascii(const char *fname, const double *data, const uint row, const uint col)
{
    FILE *wfile = fopen(fname, "w");
    uint x, y;
    for(x = 0; x < row + 1; x++)
        for(y = 0; y < col + 1; y++)
        {
            if(!y && !x)
                fprintf(wfile, "%u", col);
            else if(!x && y != 0)
                fprintf(wfile, "%u", y - 1);
            else if(!y && x != 0)
                fprintf(wfile, "%u", x - 1);
            else
                fprintf(wfile, "%g", data[(x - 1) * col + y - 1]);

            if(y == col)
                fprintf(wfile, "\n");
            else
                fprintf(wfile, " ");
        }
    fclose(wfile);
}

void wdata_bin(const char *fname, const double *data, const uint row, const uint col)
{
    uint x, y;
    float *tsp = (float *)malloc((row + 1) * (col + 1) * sizeof(float));

    for(x = 0; x < row + 1; x++)
        for(y = 0; y < col + 1; y++)
            if(!y && !x)
                tsp[0] = col;
            else if(!x && y != 0)
                tsp[x * (col + 1) + y] = y - 1;
            else if(!y && x != 0)
                tsp[x * (col + 1) + y] = x - 1;
            else
                tsp[x * (col + 1) + y] = (float)data[(x - 1) * col + y - 1];

    FILE *outfile = fopen(fname, "w");
    fwrite(tsp, sizeof(float), (row + 1) * (col + 1), outfile);
    fclose(outfile);
    free(tsp);
}

void plotdata(const double *data, const uint row, const uint col)
{
    char *tmpdat = "pltdat",
         *cmdtmp = "pltcmd";

    fprintf(stdout,
            "\nthis will create or overwrite the files '%s' and '%s'. press enter to continue.\n",
            tmpdat, cmdtmp);
    getchar();

//  wdata_bin(tmpdat, data, row, col);
    wdata_ascii(tmpdat, data, row, col);

    FILE *gnufile = fopen(cmdtmp, "w");

    fprintf(gnufile,
            "set term png size 1024, 768\n" \
            "set yl 'y'\n" \
            "set xl 'x'\n" \
            "set out 'test.png'\n" \
            "#splot '%s' binary matrix using 2:1:3 w pm3d palette t ''\n"
            "splot '%s' nonuniform matrix u 2:1:3 w pm3d palette t ''\n",
            tmpdat, tmpdat);

    fclose(gnufile);
    system("gnuplot pltcmd");
    remove(tmpdat);
    remove(cmdtmp);
}

int main(void)
{
    uint x, y,
         row = 100, col = 200;
    double *dat = (double *)malloc(row * col * sizeof(double));

    for(x = 0; x < row; x++)
        for(y = 0; y < col; y++)
            dat[x * col + y] = (double)(x << 1) * y / 100.;

    plotdata(dat, row, col);
    free(dat);
    return 0;
}

我已经删除了任何类型的有效性检查,但它也可以帮助人们通过gnuplot在C程序中直接绘制数据。要检查所描述的问题,请在wdata_asciiwdata_bin之间切换,并在splot行之间切换(仅更改#代码)。