【问题标题】:Gnuplot insert points in a parallel plotGnuplot 在平行图中插入点
【发布时间】:2015-10-06 07:09:58
【问题描述】:

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

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

或通过在绘图命令中设置 pt ps 和 pi

Gnuplot 不插入任何点。

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

我该怎么做?

谢谢

【问题讨论】:

  • Gnuplot 根本无法做到这一点。通常,这也会使您的轴拥挤,因为这些点都位于轴上。因此,您需要考虑一种不同的可视化方式(使用深蓝色和亮蓝色来区分它们)。但在不知道实际用例的情况下,这只是一些猜测。

标签: gnuplot


【解决方案1】:

不幸的是,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

但是,这产生的情节可能类似于:

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

1 2 3 5
2 1 1 6
3 3 3 7

并使用略有不同的绘图命令

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

这会产生

生成的图形看起来要好一些,但假设我们确实坚持要绘制带点的图。简单地添加像pt 1 这样的东西是行不通的。此外,它会产生一条警告消息:"test.gpl", line 17: warning: No pointtype specifier allowed, here,暗示parallel 样式根本不喜欢任何点规范。

脏修复

为了部分改进这一点,让我们按照以下步骤进行:

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 中的一些源文件进行一些操作。也就是说,我们必须

  1. 让 Gnuplot 相信绘图风格 parallel 喜欢点。为此,修改gp_types.h 中的114 行并替换

    PARALLELPLOT = 32*PLOT_STYLE_BITS + PLOT_STYLE_HAS_LINE
    

    PARALLELPLOT = 32*PLOT_STYLE_BITS + PLOT_STYLE_HAS_LINE + PLOT_STYLE_HAS_POINT
    
  2. 引入在parallel 样式内绘制点的功能。为此,必须在文件graphics.c 中找到函数plot_parallel。默认情况下它看起来像这样:

    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;
        }
    
        }
    }
    
  3. 就是这样!现在使用make &amp;&amp; make install(从目录${HOME}/gpl/gnuplot-5.0.0 调用)再次编译Gnuplot。使用${HOME}/gpl/local/bin/gnuplot ${HOME}/gpl/test.gpl(使用绘图命令plot 'data.dat' using 1:2:3:4 with parallel lc var ps 1.5)生成的输出应如下所示:

说明

  1. gp_types.h 中的修改确保最终绘图中使用的点大小规范 ps 3 不会被忽略(并且可以在 plot_parallel 函数中访问)
  2. plot_parallel函数中,我们需要引入一个指向全局终端变量的指针,即struct termentry *t = term;。然后将其用于实际绘制点。
  3. for循环遍历输入数据文件中的各个行,我们确定相应的点类型

    `point_type = plot->varcolor?((int)plot->varcolor[i]-1):plot->lp_properties.p_type;`
    

    这确保如果我们不使用lc var,则点类型由pt(或默认值)确定。如果lc var处于活动状态,则点类型取自输入数据文件中相应的数据列。

  4. 调用(*t-&gt;pointsize)(plot-&gt;lp_properties.p_size); 设置使用ps(或默认值)指定的所需点大小。
  5. 最后,(*t-&gt;point)(x0, y0, point_type); 类型的调用会使用点来扩充各个线段。

【讨论】:

  • 清晰漂亮的插件!您是否向当前的gnuplot 提出了此功能的合并请求?
猜你喜欢
  • 1970-01-01
  • 2021-07-28
  • 1970-01-01
  • 1970-01-01
  • 2012-12-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多