Gnuplot在平行坐标图中插入点

3
我需要使用gnuplot创建具有线和点的平行图。不幸的是,使用“plot with linespoints”命令时,所有的点都被连接起来了。我该如何使每个点都只与相邻的点相连?
set style line 1 lc rgb 'blue' lt 1 lw 2 pt 7 ps 0.75 pi 5

或者在绘图命令中设置pt、ps和pi。

Gnuplot不会插入任何点。

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

我该怎么做呢?

谢谢


Gnuplot 简单地无法做到这一点。通常,这也会使您的坐标轴拥挤,因为所有点都会落在坐标轴上。因此,您需要考虑不同类型的可视化(使用深蓝色和亮蓝色来区分它们)。但是,如果不知道实际用例,这只是一些猜测。 - Christoph
1个回答

3
很不幸,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样式根本不喜欢任何点说明。

临时解决方法

为了部分改善这种情况,我们可以按照以下步骤进行:
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. convince Gnuplot that the plotting style parallel likes points. For this it is sufficient to modify line 114 in gp_types.h and replace

    PARALLELPLOT = 32*PLOT_STYLE_BITS + PLOT_STYLE_HAS_LINE
    

    with

    PARALLELPLOT = 32*PLOT_STYLE_BITS + PLOT_STYLE_HAS_LINE + PLOT_STYLE_HAS_POINT
    
  2. introduce the ability to plot points within the parallel style. To this end, one has to locate the function plot_parallel in file graphics.c. By default it looks like this:

    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;
        }
    
        }
    }
    

    Let's pimp it up a little bit:

    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. and that's it! Now compile Gnuplot again with make && make install (invoked from directory ${HOME}/gpl/gnuplot-5.0.0). The output generated with ${HOME}/gpl/local/bin/gnuplot ${HOME}/gpl/test.gpl (using plotting command plot 'data.dat' using 1:2:3:4 with parallel lc var ps 1.5) should resemble this:

enter image description here

解释

  1. modification in gp_types.h ensured that the point size specification ps 3 used in the final plot is not ignored (and is accessible in the plot_parallel function)
  2. in the plot_parallel function, we need to introduce a pointer to the global terminal variable, i.e., struct termentry *t = term;. This is then used later for the actual plotting of points.
  3. in the for loop which iterates over individual lines in the input data file, we determine the corresponding point type with

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

    This ensures that if we don't use lc var then the point type is determined by pt (or default). If lc var is active, the point type is taken from the corresponding data column in the input data file.

  4. call (*t->pointsize)(plot->lp_properties.p_size); sets the desired point size specified with ps (or default).
  5. finally, calls of the type (*t->point)(x0, y0, point_type); augment individual line segments with the points.

清晰美观的附加功能!您是否向当前的“gnuplot”提交了此功能的合并请求? - John_West

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接