首页 > 解决方案 > 对特定类别栏进行分组并在 gnuplot 中提供 xtics 子类别

问题描述

我需要绘制三类数据:

每个类别都应进行不同的分组和着色。在每个组中,我们需要将不同的模式分配给框和相应的子类别作为 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 出现。你能帮我理解我哪里出错了吗?在此处输入图像描述

谢谢你。

标签: matplotlibgnuplotbar-chart

解决方案


一种可能的解决方案是使用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 ''

这给出了: 在此处输入图像描述

编辑:

从您的评论来看,我似乎误解了您的问题。为了对“每行”的框进行分组,您可以执行以下操作:

$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,i3,p1,p2,p3n1,n2,n3。该样式lc variable确保每一行都有不同的颜色。但是,如果不进行任何调整,图例中的条形图都将具有相同的颜色(因为第一行始终对应于 group 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)。这实现了图例中的项目将获得正确的颜色(蓝色而不是红色)。

结果: 在此处输入图像描述

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

编辑2:

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


推荐阅读