Search code examples
sizegnuplothistogramcustomizationbin

How to increase the size of bins of a cluster histo, with making sure that the cluster columns do not overlap?


This is the code:

############
reset session
$Data <<EOD
subject     2018/19 2021/22     
M       31.46   28.96   -2.5    
It      34.83   36.61   +1.8    
In      33.71   33.33   -0.4    
G       63.79   77.46   +13.7   
P       92.86   56.52   -36.3   
PS      67.86   60.87   -7.0    
A       21.05   65.00   +43.9   
D       53.33   54.35   +1.0    
EOD
set term svg 
set output "prova.svg"
set title "{/Arial:Bold=14 MEAN}\n {/Arial:Bold=14 2018/19 vs 2021/2022}" 
set yrange [0:100]
set ytics (0, '10' 10, '20' 20, '30' 30,'40' 40, '50' 50,'60' 60, '70' 70,'80' 80, '90' 90,'100' 100)
set grid y
set ylabel "% TOT" font ',14'
set tics scale 0
set tics font ',14'
set style fill pattern 1 border lt -1
set boxwidth 1 absolute
set key noautotitle
set key font ',14'
set xzeroaxis ls 1 lc "black"
PosX(row,col) = 0
#myColors   = "red  orange      yellow      green       cyan        blue        violet      deeppink"
myColors   = "0xff0000  0xffa500    0xffff00    0x80ff00    0x00ffff    0x0000ff    0x7f00ff    0xff1493"
myColor(i) = int(word(myColors,int(i+1)))
stats $Data u 0 nooutput   # get number of columns
N = STATS_columns
plot for [col=2:N] $Data u ($0*N+col):col:(myColor($0)) skip 1 w boxes lc rgb var, \
for [col=2:N]    '' u ($0*N+N/2.+1):(NaN):xtic(1) w boxes fill pattern col -1 lc "grey" ti columnheader(col),\
col=2    '' u ($0*N+col-3):col:(sprintf("%2.1f%%",$2))  with labels center offset 0, character 0.5 font ',9' notitle,\
col=3    '' u ($0*N+col-3):col:(sprintf("%+-.1f%%",$4)) with labels center offset 0, character 0.5 font ',9' tc lt 7 notitle
#END code
############

I want to try to increase the width of the bins (of the same size without overlap) in each bin cluster and increase the white gap beetwen the clusters to increase the size of the labels on top of the bins

enter image description here


Solution

  • Here is the slightly modified script:

    Comments:

    • you can minimize the gaps between the groups, but if you have to show 16 bars, the space for the labels will be limited. So, in order to make the labels larger I would skip the percent sign in the label. It is already on the y-axis.
    • you don*t have to set the ytics manually, you can simply set ytics 10 (check help xtics)
    • column 4 in your data did not have a header. I added a header, but then I have to correct the automatic determination of number of columns via stats, i.e. N=STATS_columns-1 since the last column will not be used for plotting bars.
    • for the labels you have to skip 1 line because you are not using the header line.
    • define a function PosX() for the x-position of the bar and the labels. Use the variable Gap to tune the gap (Gap=0 no gap).
    • use the ternary operator (check help ternary) to define a color which depends on the value. And apply the color via tc rgb var (check help lc variable).

    The script certainly can be further optimized.

    Script:

    ### grouped bar chart with adjustable gaps
    reset session
    
    $Data <<EOD
    subject 2018/19 2021/22 change
    M       31.46   28.96   -2.5
    It      34.83   36.61   +1.8
    In      33.71   33.33   -0.4
    G       63.79   77.46  +13.7
    P       92.86   56.52  -36.3
    PS      67.86   60.87   -7.0
    A       21.05   65.00  +43.9
    D       53.33   54.35   +1.0
    EOD
    
    set title "{/Arial:Bold=14 MEAN}\n {/Arial:Bold=14 2018/19 vs 2021/2022}"
    set xrange[1:]
    set ylabel "% TOT" font ',14'
    set yrange [0:100]
    set ytics 10
    set grid y
    set tics scale 0
    set tics font ',14'
    set style fill pattern 1 border lt -1
    set boxwidth 1 absolute
    set key noautotitle font ',14'
    
    #myColors       = "red       orange      yellow      green       cyan        blue        violet      deeppink"
    myColors        = "0xff0000  0xffa500    0xffff00    0x80ff00    0x00ffff    0x0000ff    0x7f00ff    0xff1493"
    myColor(i)      = int(word(myColors,int(i+1)))
    myLabelColor(v) = v>0? 0x00aa00 : v<0 ? 0xff0000 : 0x777777   # green,red,grey
    
    stats $Data u 0 nooutput   # get number of columns
    N         = STATS_columns-1
    Gap       = 0.25
    PosX(col) = (column(col))*(N-1+Gap)
    
    set term svg 
    set output "SO74502026.svg"
    
    plot for [col=2:N] $Data u (PosX(0)+col):col:(myColor($0)) skip 1 w boxes lc rgb var, \
         for [col=2:N]    '' u (PosX(0)+N/2.+1):(NaN):xtic(1) w boxes fill pattern col-1 lc "grey" ti columnheader(col),\
                 col=2    '' u (PosX(0)+col):col:(sprintf("%2.1f",$2))  skip 1 w labels center offset 0, 0.5 font ',10',\
                 col=3    '' u (PosX(0)+col):col:(sprintf("%+-.1f",$4)):(myLabelColor($4)) skip 1 w labels center offset 0, 0.5 font ',10' tc rgb var
    set output
    ### end of script
    

    Result:

    enter image description here