【问题标题】:Grouped bar plot with multiple labels in x-axisx 轴上具有多个标签的分组条形图
【发布时间】:2021-11-19 04:21:07
【问题描述】:

我正在尝试在 gnuplot 中复制接近下图的内容,因为我需要在乳胶纸上使用它。我已经尝试了很多,但我无法在底部制作两行标签。你能指导我吗?此外,如何将 % 字符作为 x 轴标签的一部分? Latex 抱怨它。

数据采用以下格式(示例)。每种不同的颜色对应不同的方法。蓝色是方法1(m1),橙色是方法2(m2),棕色是方法3(m3)

#%      system1-m1  system1-m2  system1-m3  system2-m1  ...
0.5%    16          8           15          6
1%      15          17          16          8
2%      12          10          20          15

谢谢

编辑

到目前为止我的代码如下:

set rmargin 0
set key outside tmargin center top horizontal width 3
set border
set grid
set boxwidth 0.8
set style fill solid 1.00 
set xtics nomirror rotate by 0
set format y '%1.f'
set yrange [0 to 22]
set ylabel 'Gain (\%)'
set ytics 0, 5

set style data histograms

set label 1 at -0.3, -4 '|---------System 1------------|'
set label 2 at 2.7, -4 '|---------System 2------------|'

plot "./data/metrics.dat" using 2:xtic(1) title 'Method 1' ,\
     "" using 3 title 'Method 2', \
     "" using 4 title 'Method 3',

我已经将.dat文件修改为

0.5 16  8   15
1.0 15  17  16
2.0 12  10  20
0.5 13  6   4
1.0 11  13  13
2.0 14  12  14

因为我不能让它打印 % 字符。输出图是

如您所见,它不可扩展。我必须手动放置标签(反复试验),并且 x 轴下方的标签不包含 % 字符。

【问题讨论】:

  • 到目前为止,您到底尝试了什么?您能否出示您的(非)工作代码?
  • 我已经用我的代码更新了帖子。谢谢。
  • 感谢您提供代码。我会尝试set format x '%.1f\%',但我现在无法测试。
  • 不幸的是,它不起作用。我也试过set format x "%g%%" ,但还是没有。

标签: bar-chart gnuplot


【解决方案1】:

我们已经很接近了:set format x '%.1f\%%'。以下适用于cairolatex 终端(检查help cairolatex)。

代码:

### percent sign for tic label in TeX
reset session

set term cairolatex
set output 'SO70029830.tex'

set title 'Some \TeX\  or \LaTeX\ title: $a^2 + b^2 = c^2$'
set format x '%.1f\%%'

plot x

set output
### end of code

结果:(截图)

加法

抱歉,我忘记了您问题的第二部分:标签。 此外,在您的图表中,您使用 xtic(1) 作为 tic 标签,即文本格式,因此我上面的答案中的命令 set format x '%.1f\%%' 在这里没有帮助。一种可能的解决方案是创建和使用您的特殊 TeX 标签,如下所示:

myTic(col) = sprintf('%.1f\%%',column(col))
plot $Data using 2:xtic(myTic(1))

对于标签,我会使用箭头和标签。每个直方图都放置在从0 开始的整数处。因此,箭头必须从 x 值 -0.52.5 和从 2.55.5。标签放置在 x 值 14。当然还有改进的余地。

代码:

### tic labels with % for TeX and lines/labels
reset session
set term cairolatex
set output 'SO70029830.tex'

$Data <<EOD
0.5 16  8   15
1.0 15  17  16
2.0 12  10  20
0.5 13  6   4
1.0 11  13  13
2.0 14  12  14
EOD

set rmargin 0
set key outside center top horizontal width 3
set border
set grid
set boxwidth 0.8
set style fill solid 1.00 
set xtics nomirror rotate by 0
set format y '%1.f'
set yrange [0 to 22]
set ylabel 'Gain (\%)'
set ytics 0, 5

set style data histograms
set bmargin 4

set arrow 1 from -0.5, screen 0.05 to 2.5, screen 0.05 heads size 0.05,90
set label 1 at 1, screen 0.05 'System 1' center offset 0,-0.7
set arrow 2 from 2.5, screen 0.05 to 5.5, screen 0.05 heads size 0.05,90
set label 2 at 4, screen 0.05 'System 2' center offset 0,-0.7

myTic(col) = sprintf('%.1f\%%',column(col))

plot $Data using 2:xtic(myTic(1)) title 'Method 1' ,\
     "" using 3 title 'Method 2', \
     "" using 4 title 'Method 3',
set output
### enf of code

结果:(LaTeX 文档截图)

【讨论】:

  • 非常感谢!效果很好!
【解决方案2】:

作为@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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-07-24
    • 2015-05-16
    • 1970-01-01
    • 2021-12-19
    • 1970-01-01
    • 2018-11-25
    • 2017-08-30
    • 2013-12-13
    相关资源
    最近更新 更多