GNUplot:如何使用数据中的颜色代码绘制 rowstacked 条形图?

GNUplot: how to plot rowstacked bar chart using color codes in data?

我有以下示例数据:

col1 2 0 1 1
col2 1 1 0 0
col3 1 1 1 0
col4 1 1 2 1
col5 1 1 1 1
col6 2 0 1 1
col7 1 1 2 2
col8 1 1 2 1

#4 和#5 列是#2 和#3 列的颜色代码。例如,我想要“1”代表绿色,2 代表白色,0 代表橙色。

以下是我尝试绘制它的方式:

set key off
unset border
unset xtics
unset ytics
set style data histograms
set style histogram rowstacked
set boxwidth 1 relative
set style fill solid 1.0 border -1
set yrange [0:2]
set lmargin 0
set rmargin 0
set tmargin 0
set bmargin 0.1
set terminal pngcairo truecolor size 100,65
set output "/export/test.png"
set palette model RGB defined ( 0 'orange', 1 'green', 2 'white')
plot 'test.data' u 2 linecolor rgb "orange",  '' u 3 linecolor rgb "green"

这里是我在无法根据实际数据实现颜色的情况下得到的:

Sample Image

那么如何使用数据文件中指定的实际颜色?

[万一有人想知道,万一这背后的理性鼓励你的努力;-):我正在尝试绘制一个 HP blade c7000 机箱,使用颜色编码显示空机箱插槽,插槽与blade 个电源打开和关闭。 #2 和#3 列中的实际值表示 blade 是 full-height(值为 2)还是 half-height blade(值为 1)。没有blade的地方,还是取值1,默认为half-height.]

## 更新

有了这个,我就能得到我需要的东西...有人有更短的版本吗?

plot 'test.data' u (==0?:sqrt(-1)) linecolor rgb "orange",\
    '' u (==1?:sqrt(-1)) linecolor rgb "green",\
    '' u (==2?:sqrt(-1)) linecolor rgb "white",\
    '' u (==0?:sqrt(-1)) linecolor rgb "orange",\
    '' u (==1?:sqrt(-1)) linecolor rgb "green",\
    '' u (==2?:sqrt(-1)) linecolor rgb "white"

new sample image

进一步细化

如何为块添加编号,如下图所示:

更新问题:

我注意到有时调色板会弄错颜色,除非调色板中定义的所有颜色都出现在数据中。例如,使用以下数据:

1  2 0 1 1
2  1 1 0 0
3  2 0 1 1
4  2 0 1 1
5  1 1 1 1
6  1 1 1 0
7  1 1 1 1
8  1 1 1 1

从col#4-5可以看出,我只有'green'(1)和'organge'(0)。因为我没有空槽,所以我没有 'white' 颜色。我得到这张图片:

这张图片显然是不正确的,因为白色表示我有一个空位。我期待这张图片:

那么颜色 'white' 和 'green' 是如何翻转的?我注意到如果我将这些颜色代码中的任何一个更改为白色,那么调色板就会正常工作。

颜色用于识别不同堆栈中的相应部分。因此,它们必须在属于同一直方图的所有堆栈中遵循相同的顺序。

但是 Gnuplot 有一个 newhistogram 命令,之后颜色可以是 "reset"。还有 multiplot 命令可用于在循环中添加新的直方图。

这是替换原始 plot 命令的脚本部分:

set style line 1 lt 1 lc rgb "white"
set style line 2 lt 1 lc rgb "green"
set style line 3 lt 1 lc rgb "orange"

stats 'test.data' u 2
n = STATS_records

set multiplot

do for [i=0:n-1] {
   plot "test.data" u (0) ,\
        newhistogram "" at i, "" every ::i::i u (style =  + 1, 0), \
                              "" every ::i::i u 2 ls style,          \
                              "" every ::i::i u (style =  + 1, 0), \
                              "" every ::i::i u 3 ls style
}

unset multiplot

这就是它的工作原理:

  • set style ...: 定义将要使用的样式(颜色)。
  • stats ...:求行数。我们将为每一行绘制一个独立的直方图。
  • set multiplot: 我们将在同一个区域一次又一次地绘制。
  • "test.data" u (0):不绘制任何内容,但为所有直方图保留 space。
  • new histogram "" at i:初始化一个没有名字的新直方图,在x轴上偏移i。我们将在此偏移处绘制单个堆栈。
  • "" every ::i::i:绘图行 i
  • u (style = + 1, 0):不绘制任何内容,但从文件中读取当前行的颜色。
  • u 2 ls style: 使用之前读取的样式绘制当前行的第 2 列。

我不确定这个版本是否比你的短:)

我会使用 boxxyerrorbars 绘图风格。尽管名称如此,但当您想要绘制 "different" 个框时,这就是您应该使用的。

set key off
unset border
unset xtics
unset ytics
unset colorbox
set style fill solid 1.0 border -1

set palette model RGB defined ( 0 'orange', 1 'green', 2 'white')
set cbrange [0:2]
set style data boxxyerrorbars
plot 'test.data' u 0:(0.5*):(0.5):(0.5*):4 lc palette,\
    '' u 0:( + 0.5*):(0.5):(0.5*):5 lc palette

boxxyerrorbars 绘图样式本身有四列,xydxdylc palette使用第五列中的值来确定基于当前调色板的颜色。为了使调色板中的值成为绝对值,我另外将 cbrange 设置为调色板覆盖的相同范围。

表达式using 0:(0.5*):(0.5):(0.5*):4表示:

  • 使用第零列(行号)作为x值(方框中心)
  • 第二列中的值乘以 0.5 为 y-值(方框中心)
  • 数字0.5dx(方框宽度的一半)
  • 第二列的值乘以0.5为dy-值(框高的一半)

对于第二个绘图部分,y 值是第二列中的值加上第三列中的值的一半。

这个解决方案也可以很容易地写成允许增加堆叠箱的数量:

set palette model RGB defined ( 0 'orange', 1 'green', 2 'white')
set cbrange [0:2]
set style data boxxyerrorbars

last_column = 3
plot for [i=2:last_column] 'test.data' \
    u 0:(0.5*column(i) + sum[c=2:(i-1)] column(c)):(0.5):(0.5*column(i)):(column(last_column + i - 1)) lc palette