【问题标题】:Gnuplot: categorised data - match color to data add range linesGnuplot:分类数据 - 将颜色与数据匹配添加范围线
【发布时间】:2019-02-25 09:18:17
【问题描述】:

给定一组适合某个类别的值,我想

a) 根据类别(x 轴)将数据值绘制为点(y 轴) b) 将点颜色与类别匹配 c) 每组从最小值到最大值添加一行

我所做的是使用这段代码:

set terminal png 
set output 'animals.png'
set ytics nomirror
unset key
set xrange [-0.5:5.5]

plot for [i=2:5] 'cat.dat' using i:xtic(1)
show xrange

在 x 轴上按类别成功标记,但颜色是根据列(不是行)设置的,我不知道如何添加范围栏(注意:不是误差线或百分位数,而是完整的 min->最大范围) - 特别是因为数据是按列调用的,但随后需要按行分析。不过,AFAIK gnuplot 只做列。

有什么想法吗?


上面代码的输出:

示例数据(制表符分隔):

cat 0.26    0.4 0.23    0.16
dog 0.317   0.264   0.25    0.26
bat 0.33    0.42    0.32    0.48
rat 0.59    0.62    0.57    0.56
foo 0.59    0.67    0.71    0.70
bar 0.664   0.75    0.68    0.6

【问题讨论】:

    标签: range gnuplot categories


    【解决方案1】:

    正如您所注意到的,gnuplot 不喜欢行,不幸的是(还没有?)提供转置功能。在您的解决方案中,您使用的是 Unix 系统调用/工具和 sed,它们不一定与平台无关。此外,您正在绘制点和单独的箭头来连接,如果您不坚持在最小值和最大值处使用水平条,我想您可以通过 linespoints 简化这一点。

    让我展示一些“简化的”独立于平台的 gnuplot-代码。

    一般程序:

    1. 加载文件到数据块
    2. 转置数据块
    3. 用线点绘制列

    数据文件制表符分隔,不带标题:Animals.dat

    cat 0.26    0.4 0.23    0.16
    dog 0.317   0.264   0.25    0.26
    bat 0.33    0.42    0.32    0.48
    rat 0.59    0.62    0.57    0.56
    foo 0.59    0.67    0.71    0.70
    bar 0.664   0.75    0.68    0.6
    

    下面的代码需要一个 FileToDatablock 例程和一个 DatablockTranspose 例程。

    将文件加载到数据块的过程:FileToDatablock.gpp

    ### Load datafile "as is" into datablock for different platforms
    # ARG1 = input filename
    # ARG2 = output datablock
    
    if (GPVAL_SYSNAME[:7] eq "Windows") {          # "Windows_NT-6.1" is shown on a Win7 system
        load '< echo '.ARG2.' ^<^<EOD & type "'.ARG1.'"'
    }
    if (GPVAL_SYSNAME eq "Linux") {                # that's shown on a Raspberry
        load '< echo "\$Data << EOD" & cat "'.ARG1.'"'
    }
    if (GPVAL_SYSNAME eq "Darwin") {               # this was shown on a MacOS Sierra 10.12.6
        load '< echo "\$Data << EOD" & cat "'.ARG1.'"'  # identical to Linux
    }
    ### end of code
    

    转置数据块的gnuplot过程:DatablockTranspose.gpp

    ### transpose datablock (requires whitespace as separator)
    # ARG1 = Input datablock
    # ARG2 = Output datablock
    
    set print @ARG2
    do for [DBT_i=1:words(@ARG1[1])] { 
        DBT_Line = ""
        do for [DBT_j=1:|@ARG1|] {
           DBT_Line = DBT_Line.word(@ARG1[DBT_j],DBT_i).\
           (DBT_j < |@ARG1| ? "\t" : "")
        }
        print DBT_Line
    }
    set print
    undefine DBT_*
    ### end of code
    

    实际代码:

    ### plotting rows
    reset session
    
    # load file to datablock
    call "FileToDatablock" "Animals.dat" "$Data"
    
    # transpose datablock by gnuplot procedure
    call "DatablockTranspose.gpp" "$Data" "$DataTransposed"
    
    set palette defined ( 0 'purple', 1 'blue', 2 'green', \
        3 'yellow', 4 'orange', 5 'red' , 6 'black' )
    unset colorbox
    
    set xrange[0.5:|$Data|+0.5]
    plot for [i=1:|$Data|] $DataTransposed u (i):i:(i):xtic(columnhead(i)) w lp pt 7 ps 1.5 lc palette not
    ### end of code
    

    结果:

    【讨论】:

    • linespoints 肯定是有意义的,并且在较大的集合上可以节省时间 - 我忘记了在换位后会朝着所需的方向前进。我猜,转置似乎是一个有价值的功能请求。
    【解决方案2】:

    这需要多走几步,最重要的是,每个类别都被赋予一个唯一的索引号,并且数据被转置:

    (这里我会参考 GNU unix shell 命令)

    $cat -n data_orig.dat | datamash transpose > data_trans.dat
    $cat data_trans.dat  #added spaces for readability
    
         1       2       3       4       5       6
    cat     dog     bat     rat     foo     bar
    0.26    0.317   0.33    0.59    0.59    0.664
    0.4     0.264   0.42    0.62    0.67    0.75
    0.23    0.25    0.32    0.57    0.71    0.68
    0.16    0.26    0.48    0.56    0.70    0.6
    

    现在可以按列正确分析数据,并根据索引号定义颜色。 条形图由箭头组成,其中最小值和最大值取自每列的统计分析。 通过系统调用将xticlabels 读入一维word 数组(这是一个内部gnuplot 函数),并使数组索引与数据列的唯一索引匹配。

    脚本有非常详细的解释,以更好地支持新的 gnuplot 用户:

    #output and style settings: make png-file, name it 'animals.png',
    #   yaxis tics on both sides, no legend
    set terminal png 
    set output 'animals.png'
    set ytics mirror
    unset key
    
    #data indices are integers from 1 to 6, a bit of space for the looks
    set xrange [0.5:6.5] 
    
    #define color scheme for each data series
    set palette defined ( 0 'purple', 1 'blue', 2 'green', \
        3 'yellow', 4 'orange', 5 'red' , 6 'black' )
    
    #hide color gradient bar of palette
    unset colorbox
    
    #define array names using word function:
    #  read in 2nd line of data by system call and run through words
    #  each space-delimited word is now an array element of names
    names(n) = word( system("sed -n '2p' cat.dat_t" ) , n )
    
    #create min->max bars
    #loop over all data sets to create bars
    do for [i=1:6] {
    
        #among others this gives minimum and maximum values of the data set
        #using i -> only handle column i in statistics
        #every ::3 start with row 3 for statistical analysis
        stats 'data_trans.dat' using i every ::3
    
        #use min/max values for arrow y positions, index i for x positions
        #heads = arrow head on both sides
        #size 0.1,90 = 0.1 line lengths for arrow head
        #          and 90° arrow head line angles = T bar style
        #lc palette cb i = use line color (lc) from palette value matching
        #   color bar (cb) value of index i
        set arrow from i,STATS_min to i,STATS_max heads size 0.1,90 lc palette cb i
    
    }
    
    #plotting:
    #   for [i=1:6] loop over all 6 columns, use i as loop variable
    #   every ::3 start with row 3 for data plotting
    #   using (i):i:(i):xtic(names(i))
    #         syntax of using
    #         x-value:y-value:z-value:label_x_axis [:label_y_axis:label_z_axis]
    #         (i) -> literal value of i for x and z, z is used as color definition
    #         i -> y-values from column i
    #         xtic(names(i)) get element i of array names for xtic label
    #   lc palette -> coloring according to defined palette
    #   pt 7 ps 1.5 -> point style and size definition
    plot for [i=1:6] 'data_trans.dat' every ::3 using (i):i:(i):xtic(names(i)) lc palette pt 7 ps 1.5
    

    参考资料:

    coloring based on x-values

    array from word function

    结果:


    编辑:

    如@theozh 的答案所示,linespoints 显示范围更为实用。这允许通过在绘图命令行中添加w lp 来跳过整个条形/箭头创建块。

    【讨论】:

      猜你喜欢
      • 2015-07-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-04
      相关资源
      最近更新 更多