仅在 gnuplot 直方图中的几个条形上插入标签

问题描述 投票:0回答:2

我正在用以下代码绘制直方图

set style data histogram
#clustered
#set terminal wxt enhanced persist
set term post eps enhanced "Times-Roman, 14"
set output 'tostack.eps'    #change here
#set boxwidth 0.9 
set grid
set auto y
#set auto x
set auto y
#set ylabel format "{/:Bold}"
#set size 1.35,0.35
#set title ""
set style histogram clustered gap 1 title offset 1,0.25
set ylabel "\nXXX (in %)\n\n" font "Times-Roman ,25"     #change here
set xlabel "\nYYY \n" font "Times-Roman,25"                 #change here
#set style fill solid noborder
set style fill pattern  border -1
set key right
set key spacing 3 font "Times-Roman,20"
set xtics font ", 20"
set ytics font ", 20"

plot for [COL=2:5] 'tostack.dat' using COL:xticlabels(1) title columnheader fs pattern 2

我的数据文件是

AA  BB      CC      DD      EE
100 23.6491500555   6.9743235667    6.5497090218    6.9819639165
200 6.4522741669    14.0817294443   15.1392548608   4.4619875307
300 8.8030456951    8.1386311242    12.5224139497   6.7637627586
400 25.7698157655   7.6673254026    10.0040799765   11.7883595409

在生成的直方图中,如何只为每组中值较大的那些条插入标签。

请帮助我将这些标签加粗。

gnuplot histogram labeling
2个回答
2
投票

为了找到每组中的最大值,很可能需要使用外部处理工具。例如,可以使用 gawk,如下所示。这个想法是跳过标题(条件

NR>1
)并在每一行中查找具有最大值的列号(假设您的数据文件有 4 个数据列,该数字将为 2、3、4 或 5) 。现在,在直方图中,各组框连续居中于 0、1、2 等。有 4 个数据列(且
boxwidth
设置为 1),每个框的宽度为 0.2(两个框之间的 4 个框)每组 + 一个用于“空间”的空框)。为了找到放置标签的 x 坐标,需要将数字
2,3,4,5
转换为
b-0.3,b-0.1,b+0.1,b+0.3
,其中 b 表示该组从 0 开始的数字:

set terminal postscript eps enhanced "Times-Roman" 14
set output 'tostack.eps'

set grid

set boxwidth 1.0
set style data histogram
set style histogram clustered gap 1 title offset 1,0.25

set ylabel "XXX (in %)" font "Times-Roman, 25"
set xlabel "YYY" font "Times-Roman, 25"

set style fill pattern border -1
set key right
set key spacing 3 font "Times-Roman, 20"

set xtics font ",20"
set ytics font ",20"

plot \
    for [COL=2:5] 'tostack.dat' using COL:xticlabels(1) title columnheader fs pattern 2, \
    "<gawk 'NR>1{ \
        j=0; \
        for(i=2;i<=NF;i++){ \
            if(i == 2 || $i > m){ \
                m=$i;j=i; \
            } \
        } \
        print (NR-2)+(0.2*j-0.7), m; \
    }' tostack.dat" u 1:2:(sprintf("%.3f", column(2))) t "" w labels offset 0,char 1 font "Times-Bold, 16"

然后产生: enter image description here

编辑: 如果要在每列中选择最大值,只需稍微修改过滤脚本(计算标签位置背后的想法保持不变):

set terminal postscript eps enhanced "Times-Roman" 14
set output 'tostack.eps'

set grid

set boxwidth 1.0
set style data histogram
set style histogram clustered gap 1 title offset 1,0.25

set ylabel "XXX (in %)" font "Times-Roman, 25"
set xlabel "YYY" font "Times-Roman, 25"

set style fill pattern border -1
set key right
set key spacing 3 font "Times-Roman, 20"

set xtics font ",20"
set ytics font ",20"

plot \
    for [COL=2:5] 'tostack.dat' using COL:xticlabels(1) title columnheader fs pattern 2, \
    "<gawk '\
        NR>1{ \
            for(i=2;i<=NF;i++){ \
                if(NR == 2 || $i > m[i-2]){ \
                    m[i-2]=$i; \
                    p[i-2]=NR-2; \
                } \
            } \
        } \
        END{ \
            for(i=0;i<4;i++){ \
                print p[i] + (0.2*i - 0.3), m[i]; \
            } \
        } \
    ' tostack.dat" u 1:2:(sprintf("%.1f", $2)) t "" w labels offset char 0,char 0.5 font "Times-Bold, 12" rotate by 0

产生: enter image description here


0
投票

在您的情况下,不需要像

awk
gawk
这样的外部工具,您只需使用 gnuplot only 即可完成,因此,与平台无关。 甚至有一个解决方案可以与 gnuplot 4.4.3(OP 版本)一起使用,使用一些奇怪的动作和外部文件(因为当时数据块不可用)。如果有人问我要4.4.3版本,我可以提供。因此,现在,我将为 gnuplot>=5.0.3 提供一个 gnuplot-only 版本,其中数据作为数据块包含在脚本中。

一些解释:

  • 数据使用选项矩阵(选中

    help matrix
    )绘制到数据块
    $Max
    中。
    $Max
    中的第一列包含行索引,第二列包含当前最大值,第三列包含包含当前最大值的列号。

  • 通过这样做,在行索引(第 1 列)更改之前,每组的最大值会被记住在最后一行中。

  • 然后您可以使用绘图样式

    $Max
    绘制
    with labels
    并相应地放置值。

  • 数据块

    $Max
    看起来像这样:

 0       nan             1
 0       23.6492         1
 0       23.6492         1
 0       23.6492         1
 0       23.6492         1
 1       nan             1
 1       6.45227         1
 1       14.0817         2
 1       15.1393         3
 1       15.1393         3
 2       nan             1
 2       8.80305         1
 2       8.80305         1
 2       12.5224         3
 2       12.5224         3
 3       nan     1
 3       25.7698         1
 3       25.7698         1
 3       25.7698         1
 3       25.7698         1

脚本:(适用于 gnuplot>=5.0.3,2016 年 2 月)

### grouped barchart with label only on max of each group
reset session

$Data <<EOD
AA    BB              CC              DD              EE
100   23.6491500555   6.9743235667    6.5497090218    6.9819639165
200   6.4522741669    14.0817294443   15.1392548608   4.4619875307
300   8.8030456951    8.1386311242    12.5224139497   6.7637627586
400   25.7698157655   7.6673254026    10.0040799765   11.7883595409
EOD

set table $Max
    plot $Data skip 1 matrix u (c=$1, r=$2): ($1==0 ? (max=NaN,cmax=1) : \
         $1==1 ? max=$3:0, $3>max ? (max=$3,cmax=$1):0, max):(cmax) w table
unset table

set style data histogram
set style histogram clustered gap 1
set style fill pattern border -1
set xrange [-0.6:r+0.6]
set key out noautotitle
set tics out
set grid x,y

plot for [col=2:5] $Data u col:xtic(1) title columnheader, \
     $Max every c+1::r+1 u ($1-0.5+$3/(c+1)):2:2 w labels center offset 0,0.7
### end of script

结果:

Output graph wxt terminal

© www.soinside.com 2019 - 2024. All rights reserved.