This takes a few more steps, above all, each category is given a unique index number, and the data is transposed:
(I'll refer to GNU unix shell commands here)
$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
Now the data can be properly analyzed in columns and colors be defined according to the index number.
The bars are made with arrows, where minimum and maximum are taken from the statistical analysis of each column.
The xticlabels
are read into a 1D word
array (this is an internal gnuplot
function) with a system call and the array indices are made to match the unique indices of the data columns.
The script with very detailed explanations to better support new gnuplot users:
#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
References:
coloring based on x-values
array from word
function
Result:

EDIT:
As shown in @theozh 's answer, linespoints
are far more practicable for showing the range. This allows skipping the whole bar/arrow creation block by just adding w lp
in the plotting command line.