Gnuplot 在平行图中插入点

标签 gnuplot

我需要使用 gnuplot 创建一个带有线和点的平行图。
不幸的是,要么使用

set style line 1 lc rgb 'blue' lt 1 lw 2 pt 7 ps 0.75 pi 5

或者通过在 plot 命令中设置 pt ps 和 pi

Gnuplot 不插入任何点。

我需要插入点来区分两条颜色相同的线。
它们必须是相同的颜色,因为它们属于同一个“家族”。因此,我不能简单地改变颜色:(

我怎样才能做到这一点?

谢谢

最佳答案

不幸的是,Gnuplot 不支持“开箱即用”的这个特性,但是如果你需要它只是为了一些快速的一次性生产绘图,那么有一种稍微肮脏的方法来做到这一点。更具体地说,可以获取 Gnuplot 的当前源代码,以一种或多或少令人满意的方式引入此功能并使用 Gnuplot 的修改版本生成所需的图形。

为了说明这个想法,假设我们要平行绘制以下数据文件 data.dat仅由三个“集合”组成:

1 2 3
2 1 1
3 3 3

受默认 Gnuplot 演示的启发 parallel.dem ,人们可能会尝试使用脚本来实现这一点 test.gpl像这样:
set title "Parallel Axis Plot" font ",15"

set terminal pdf
set output 'test.pdf'

set border 0
unset key
set xrange [] noextend
unset ytics

# use x-axis tic positions to label the axes
set xtics 1 format "axis %g" scale 0,0

# turn on axis tics for the parallel axes
set for [i=1:3] paxis i tics

plot 'data.dat' using 1:2:3 with parallel

然而,这产生的情节可能类似于:
enter image description here

在这里,所有线条的类型和颜色都相同,这很令人困惑。作为一个小的升级,让我们修改我们的输入数据文件如下:
1 2 3 5
2 1 1 6
3 3 3 7

并使用略有不同的绘图命令
plot 'data.dat' using 1:2:3:4 with parallel lc var

这产生

enter image description here

结果图看起来好一点,但假设我们确实坚持有一个带点的情节。只需添加类似 pt 1 的内容不起作用。此外,它会生成一条警告消息:"test.gpl", line 17: warning: No pointtype specifier allowed, here暗示parallel style 根本不喜欢任何点规范。

肮脏的修复

为了部分改进这一点,让我们继续如下:
cd ${HOME}

#prepare a sand box directory
mkdir gpl
cd gpl

#download the latest version
wget -O gnuplot_latest.tgz http://sourceforge.net/projects/gnuplot/files/latest/download?source=files
tar -xzvf gnuplot_latest.tgz

cd gnuplot-5.0.0
./configure --prefix=${HOME}/gpl/local
make && make install

在这里,我们假设我们的系统已经具备成功构建所需的所有先决条件。例如在 Ubuntu 上,这种最小情况下的场景可能只需要 libpango 和 libreadline 的开发包。

现在,我们需要使用存储在 ${HOME}/gpl/gnuplot-5.0.0/src 中的一些源文件。 .也就是说,我们必须
  • 说服 Gnuplot 绘图风格 parallel喜欢点。为此,修改行 114 就足够了在 gp_types.h并替换
    PARALLELPLOT = 32*PLOT_STYLE_BITS + PLOT_STYLE_HAS_LINE
    


    PARALLELPLOT = 32*PLOT_STYLE_BITS + PLOT_STYLE_HAS_LINE + PLOT_STYLE_HAS_POINT
    
  • 引入在 parallel 内绘制点的能力风格。为此,必须定位函数plot_parallel在文件中 graphics.c .默认情况下,它看起来像这样:
    static void
    plot_parallel(struct curve_points *plot)
    {
        int i, j;
        int x0, y0, x1, y1;
    
        for (i = 0; i < plot->p_count; i++) {
    
        /* rgb variable  -  color read from data column */
        check_for_variable_color(plot, &plot->varcolor[i]);
    
        x0 = map_x(1.0);
        y0 = AXIS_MAP(PARALLEL_AXES+0, plot->z_n[0][i]);
        for (j = 1; j < plot->n_par_axes; j++) {
            x1 = map_x((double)(j+1));
            y1 = AXIS_MAP(PARALLEL_AXES+j, plot->z_n[j][i]);
            draw_clip_line(x0, y0, x1, y1);
            x0 = x1;
            y0 = y1;
        }
    
        }
    }
    

    让我们稍微整理一下:
    static void
    plot_parallel(struct curve_points *plot)
    {
        int i, j;
        int x0, y0, x1, y1;
    
        int point_type;
        struct termentry *t = term;
    
        for (i = 0; i < plot->p_count; i++) {
    
        /* rgb variable  -  color read from data column */
        check_for_variable_color(plot, &plot->varcolor[i]);
        point_type = plot->varcolor?((int)plot->varcolor[i]-1):plot->lp_properties.p_type;
    
        x0 = map_x(1.0);
        y0 = AXIS_MAP(PARALLEL_AXES+0, plot->z_n[0][i]);
    
       (*t->pointsize)(plot->lp_properties.p_size);
       (*t->point)(x0, y0, point_type);
    
        for (j = 1; j < plot->n_par_axes; j++) {
            x1 = map_x((double)(j+1));
            y1 = AXIS_MAP(PARALLEL_AXES+j, plot->z_n[j][i]);
            draw_clip_line(x0, y0, x1, y1);
            (*t->point)(x1, y1, point_type);
            x0 = x1;
            y0 = y1;
        }
    
        }
    }
    
  • 就是这样!现在用 make && make install 再次编译 Gnuplot (从目录 ${HOME}/gpl/gnuplot-5.0.0 调用)。使用 ${HOME}/gpl/local/bin/gnuplot ${HOME}/gpl/test.gpl 生成的输出(使用绘图命令 plot 'data.dat' using 1:2:3:4 with parallel lc var ps 1.5 )应该类似于:

  • enter image description here

    解释
  • 修改 gp_types.h确保点大小规范ps 3在最终图中使用的不会被忽略(并且可以在 plot_parallel 函数中访问)
  • plot_parallel函数,我们需要引入一个指向全局终端变量的指针,即struct termentry *t = term; .这随后用于实际绘制点。
  • for循环遍历输入数据文件中的各个行,我们确定相应的点类型
    `point_type = plot->varcolor?((int)plot->varcolor[i]-1):plot->lp_properties.p_type;`
    

    这确保如果我们不使用 lc var那么点类型由pt决定(或默认)。如 lc var处于事件状态时,点类型取自输入数据文件中的相应数据列。
  • 调用 (*t->pointsize)(plot->lp_properties.p_size);设置由 ps 指定的所需点大小(或默认)。
  • 最后,类型为 (*t->point)(x0, y0, point_type); 的调用用这些点增加单独的线段。
  • 关于Gnuplot 在平行图中插入点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32963824/

    相关文章:

    gnuplot:数据矩阵的2D图

    gnuplot - 在 Gnuplot 中根据日期和值绘制日事件

    gnuplot 等高线图阴影线

    dictionary - Gnuplot:如何在 Axis 和 pm3d map 之间有一些空间

    php - Gnuplot 中某些特定值的不同颜色的颜色条

    gnuplot - 如何修复 Gnuplot 中的 "Cannot open load file"?

    plot - Gnuplot:磅值单位

    gnuplot tikz 终端

    graph - 如何在 Gnuplot 中创建蜘蛛图?