作为@theozh 答案的替代方案,已经有一个名为newhistogram 的内置函数直接允许在x 轴下方放置标签。
在处理涉及newhistogram 的答案时,我发现了水平键布局的错误,现在由于 Ethan 已修复。因此,借助最新的 gnuplot 开发版本,我能够提供一种解决方案,允许进行更多微调,例如更改组间间距的能力。
set terminal cairolatex standalone colour header '\usepackage{siunitx}' size 25cm, 7cm
# generate some random data in your format
N = 7
set print $MYDATA
do for [i=1:N] {
print sprintf('0.5 %f %f %f', rand(0)*20, rand(0)*20, rand(0)*20)
print sprintf('1.0 %f %f %f', rand(0)*20, rand(0)*20, rand(0)*20)
print sprintf("2.0 %f %f %f", rand(0)*20, rand(0)*20, rand(0)*20)
}
unset print
# define the look
set style data histograms
set style fill solid 1.00
set boxwidth 0.8
set key horizontal outside t c width 1
set xr [-1:27]
set xtics nomirror
set ytics out 5 nomirror
set grid y # I don't think vertical grid lines are needed here
set ylabel 'Gain/\%'
set rmargin 0.01
set bmargin 3
至于 tic 标记,我稍微调整了@theozh 的答案——因为您已经在使用 LaTeX,您不妨通过siunitx 解析数字,这将确保数字和单位之间的间距正确:
myTic(col) = sprintf('\SI{%.1f}{\%}',column(col))
您提供的屏幕截图中的垂直分隔标记可以迭代创建:
do for [i=1:N+1] {set arrow i from first -1+(i-1)*4, graph 0 to first -1+(i-1)*4, screen 0 lw 2 nohead}
现在是实际的绘图命令:
plot newhistogram "System 1" offset 0,-0.5 lt 1, for [i=1:3] $MYDATA using (column(i+1)):xtic(myTic(1)) every ::0::2 title sprintf('Method %.0f',i), \
newhistogram "System 2" offset 0,-0.5 lt 1 at 4, for [i=1:3] $MYDATA using (column(i+1)):xtic(myTic(1)) every ::3::5 not, \
newhistogram "System 3" offset 0,-0.5 lt 1 at 8, for [i=1:3] $MYDATA using (column(i+1)):xtic(myTic(1)) every ::6::8 not, \
newhistogram "System 4" offset 0,-0.5 lt 1 at 12, for [i=1:3] $MYDATA using (column(i+1)):xtic(myTic(1)) every ::9::11 not, \
newhistogram "System 5" offset 0,-0.5 lt 1 at 16, for [i=1:3] $MYDATA using (column(i+1)):xtic(myTic(1)) every ::12::14 not, \
newhistogram "System 6" offset 0,-0.5 lt 1 at 20, for [i=1:3] $MYDATA using (column(i+1)):xtic(myTic(1)) every ::15::17 not, \
newhistogram "System 7" offset 0,-0.5 lt 1 at 24, for [i=1:3] $MYDATA using (column(i+1)):xtic(myTic(1)) every ::18::20 not
这看起来很糟糕,这是怎么回事?
newhistogram 创建一组新的直方图框,它的第一个参数是一个放在 x 轴下方的字符串。它还被告知将线型计数器重置为 1。
然后迭代地绘制数据的三列,但不是一次绘制所有行,而只是前三行,并带有相应的键条目。
然后创建另一个新直方图,并告诉它从 x 值 4 开始(无论如何这将是默认值)。现在绘制接下来的三行,依此类推。
现在,每次调用newhistogram 时,都会在键中添加一个空行,从而导致键放置出现问题。因此Ethan引入的新关键字是
set style histogram nokeyseparators
这将禁用此行为。
如您所见,组之间的空间比内部大。您可能需要更改newhistogram at ... 中的数字并相应地调整垂直线位置的计算。
plot 命令当然是高度重复的,最好让它成为一个迭代调用。不幸的是,在plot 调用中不可能进行跨越多个对象的迭代。但是,可以迭代地将绘图命令字符串放在一起(过度使用字符串连接.)然后绘制它。
A = 'newhistogram "System '
B = '" offset 0,-0.5 lt 1'
C = 'for [i=1:3] $MYDATA using (column(i+1)):xtic(myTic(1)) every ::'
myplotstring = A.'1'.B.', '.C."0::2 title sprintf('Method %.0f',i),"
do for [i=2:N] {myplotstring = myplotstring.A.i.B.'at '.(4*(i-1)).', '.C.(3*i-3).'::'.(3*i-1).' not, '}
plot @myplotstring