组类别特定栏并在gnuplot中提供xtics子类别

时间:2018-05-23 18:15:08

标签: matplotlib gnuplot bar-chart

我需要绘制三类数据:

  • cat1(带子类别i1,i2,i3)
  • cat2(子类别为p1,p2,p3)
  • cat3(子类别为n1,n2,n3)

每个类别应按不同方式分组和着色。在每个组中,我们需要将不同的模式分配给框和相应的子类别作为xtic标签,因为它需要提供用于区分。

以下是示例数据和代码。 样本数据:sample.dat

cat1 i1 95.2162 0.817947 i2 96.2065 0.710029 i3 98.4846 0.58444 
cat2 p1 96.899 0.502756 p2 97.9695 1.16202 p3 99.631 0.0911258 
cat3 n1 99.4709 0.318714 n2 99.5897 0.234542 n3 99.9535 0.0507579

代码:

set terminal png
set output 'bar.png'
set style data histograms
set style fill solid 1 border lt -1
set boxwidth 0.9
set style histogram errorbars lw 3
plot 'sample.dat' using 3:4:xtic(2) title "cat1", \
     ''             using 6:7:xtic(5) title "cat2", \
     ''             using 9:10:xtic(8) title "cat3"

请找到图表输出。所需的输出是将组合条形图组合成一种颜色,并且需要具有特定子类别作为xtic标签。但是这里的输出失败并且在所有类别中显示3种颜色,并且每组只有最后的xtic。能帮我理解错误的地方吗? enter image description here

谢谢。

1 个答案:

答案 0 :(得分:1)

一种可能的解决方案是使用with boxes绘图样式生成单个组,然后叠加错误栏。下面的脚本将boxwidth设置为1,然后按固定数量(4和8)偏移各个组。由于每组中只有3个盒子,这在组之间提供了足够的“间隙”(与每个盒子一样宽)。

$DATA <<EOD
cat1 i1 95.2162 0.817947 i2 96.2065 0.710029 i3 98.4846 0.58444 
cat2 p1 96.899 0.502756 p2 97.9695 1.16202 p3 99.631 0.0911258 
cat3 n1 99.4709 0.318714 n2 99.5897 0.234542 n3 99.9535 0.0507579
EOD

set terminal pngcairo enhanced rounded font ",16"
set output 'fig.png'

set style fill solid 1 border lt -1
set boxwidth 1.0

set linetype 42 lw 2 lc rgb 'black'
set yr [94:102]

set xtics out nomirror

plot \
  $DATA using (0 + $0):3:xtic(2) w boxes lc rgb 'red' t 'cat1', \
  $DATA using (0 + $0):3:4 w yerrorbars lt 42 t '', \
  $DATA using (4 + $0):6:xtic(5) w boxes lc rgb 'green' t 'cat2', \
  $DATA using (4 + $0):6:7 w yerrorbars lt 42 t '', \
  $DATA using (8 + $0):9:xtic(8) w boxes lc rgb 'blue' t 'cat3', \
  $DATA using (8 + $0):9:10 w yerrorbars lt 42 t ''

这给出了: enter image description here

编辑:

从您的评论中,我似乎误解了您的问题。为了对“每行”分组,您可以这样做:

$DATA <<EOD
cat1 i1 95.2162 0.817947 i2 96.2065 0.710029 i3 98.4846 0.58444 
cat2 p1 96.899 0.502756 p2 97.9695 1.16202 p3 99.631 0.0911258 
cat3 n1 99.4709 0.318714 n2 99.5897 0.234542 n3 99.9535 0.0507579
EOD

set terminal pngcairo enhanced rounded font ",16"
set output 'fig.png'

set style fill solid 1 border lt -1
set boxwidth 1.0

set linetype 42 lw 2 lc rgb 'black'
set yr [94:102]

set xtics out nomirror

set lt 1 lc rgb 'red'
set lt 2 lc rgb 'blue'
set lt 3 lc rgb 'green'


plot \
  $DATA using (4*$0):3:($0+1):xtic(2) w boxes lc variable t 'cat1', \
  $DATA using (4*$0):3:4 w yerrorbars lt 42 t '', \
  $DATA using (4*$0 + 1):6:($0+1):xtic(5) w boxes lc variable t '', \
  $DATA using (4*$0 + 1):(1/0):($0+2) w boxes lc variable t 'cat2', \
  $DATA using (4*$0 + 1):6:7 w yerrorbars lt 42 t '', \
  $DATA using (4*$0 + 2):9:($0+1):xtic(8) w boxes lc variable t '', \
  $DATA using (4*$0 + 1):(1/0):($0+3) w boxes lc variable t 'cat3', \
  $DATA using (4*$0 + 2):9:10 w yerrorbars lt 42 t ''

这里的想法是,与第一批列的行对应的框放置在位置0, 4, 8,这些框对应于位置1, 5, 9的第二批行,最后2, 6, 10的第三批。这有效地创建了分组i1,i2,i3p1,p2,p3n1,n2,n3。样式lc variable确保每行获得不同的颜色。但是,如果没有任何调整,图例中的条形都将具有相同的颜色(因为第一行始终对应于组i1,i2,i3)。要解决此问题,脚本使用:

$DATA using (4*$0 + 1):6:($0+1):xtic(5) w boxes lc variable t '', \
$DATA using (4*$0 + 1):(1/0):($0+2) w boxes lc variable t 'cat2'

这里,第一个语句执行绘图,而第二个语句生成空图(由于未定义的值1/0),但使用颜色索引移1,即($0+2)代替($0+1)。这实现了图例中的项目将获得正确的颜色(蓝色而不是红色)。

结果: enter image description here

最后,语句$DATA表示数据块。较旧版本的Gnuplot(我猜不到5个)不支持此功能,因此您可以用包含包含数据的文件名的变量替换$DATA

EDIT2:

更具体地说,例如表达式(4*$0 + 1):6:($0+1):xtic(5)请求在x坐标处生成框,计算为行数(从0开始)加1的4倍。框的高度取自第6列,颜色索引($0+1)计算为一个加上行号,最后从第5列加载xtic标签。