gnuplot:如何实现多色标签?

gnuplot: How to realize multicolor labels?

gnuplot如何实现多色标签? 显然,增强的文本模式提供了字体、字体大小、粗体、斜体等参数。 但不是颜色。 以下解决方法改编自 here.

它将标签分成与您拥有的颜色一样多的标签,并使用增强的文本函数 &{space} 插入长度为 space 的空 space。

有没有更好的方法?

代码:

### multicolor labels
reset session

Text1 = "One";   Color1 = "red"
Text2 = "Two";   Color2 = "green"
Text3 = "Three"; Color3 = "blue
Text4 = "Four";  Color4 = "magenta"
Text5 = "Five";  Color5 = "cyan"
Text6 = "Six";   Color6 = "yellow"

PosX=0
PosY=0
set label 1 Text1 at PosX,PosY tc rgb Color1
set label 2 sprintf("&{%s}%s",Text1,Text2) at PosX,PosY tc rgb Color2
set label 3 sprintf("&{%s%s}%s",Text1,Text2,Text3) at PosX,PosY tc rgb Color3
set label 4 sprintf("&{%s%s%s}%s",Text1,Text2,Text3,Text4) at PosX,PosY tc rgb Color4
set label 5 sprintf("\n%s",Text5) at PosX,PosY tc rgb Color5
set label 6 sprintf("\n&{%s}%s",Text5,Text6) at PosX,PosY tc rgb Color6

plot x
###end of code

结果:(实际上是set terminal wxt font ",20"

使用任何终端的唯一方法似乎是您展示的那个。

我不知道这是否是更好的方法,但我会向您展示如何按照与您相同的方式进行操作,但使用“标签”绘图样式。

代码:

set terminal wxt font ",20"

$text <<EOD
"One"   0xff0000
"Two"   0x00ff00
"Three" 0x0000ff
"Four"  0xff00ff

"Five"  0x00ffff
"Six"   0xffff00
EOD

###########################################
# Rearrangement of data for "with labels"
###########################################
stat $text using 0 nooutput
set print $labels
line = "&{"
do for [i=1:STATS_records+STATS_blank] {
  if ( words($text[i]) == 0 ) {
    string = "\n"
    color  = "black"
    cooked = line . "}" . string
    line   = cooked . "&{" 
  } else {
    string = word($text[i],1)
    color  = word($text[i],2)
    cooked = line . "}" . string
    line   = line . string
  }
  print sprintf('"%s" %s', cooked, color)
}
set print
###########################################

set xrange [-10:10]
set yrange [-10:10]

plot x,\
     $labels using (0):(0):1:2 with labels tc rgb variable left enhanced title ""

pause -1

数据块$text的每一行代表一个字符串和一种颜色(颜色为整数)。空行表示换行。根据这些数据,我们使用“&{string}”重建字符串数据并将其传递给“with labels”。


如果你允许使用外部命令'sed',你可以使用以下trickkey方法,但只能在svg终端中使用。

代码:

# This filter unescapes '<tspan', '</tspan' in svg output
filter = "| sed -e 's/&lt;tspan/<tspan/g' -e 's/&lt;\/tspan/<\/tspan/g' > "

set terminal svg font ",20"
set output filter . "test.svg"

labeltext = "<tspan fill='red' >One</tspan>" . \
            "<tspan fill='green'>Two</tspan>" . \
            "<tspan fill='blue'>Three</tspan>" . \
            "<tspan fill='magenta'>Four</tspan>" . \
            "\n" . \
            "<tspan fill='cyan'>Five</tspan>" . \
            "<tspan fill='yellow'>Six</tspan>" 

set label labeltext at 0,0 

plot x

pause -1

在此示例中,标签文本嵌入了 SVG 标签。 Gnuplot 将 '<' 转义为 '<'在输出 SVG 时,所以我们使用“sed”过滤器对其进行反转义。

只是为了好玩,这是另一种“自动化”方法。您可以通过 {/:<color> <your text>} 设置颜色,类似于增强文本模式。

我知道 gnuplot 不是解析字符串的理想选择,并且以下过程并不适用于所有情况,例如对于超过两行的彩色文本,您必须将颜色设置两次。也许整个过程可以打包成函数和宏。好吧,它做了预期的事情,但不是很方便。欢迎简化和改进。

代码:

### multicolor label
reset session
 
myLabel = "This is {/:red red}, this is {/:green green}, \nand this is {/:blue blue}.\nHere is {/:magenta magenta}\n{/:magenta over two} lines."

# splitting the label
s = myLabel
myLabelSplit = ''
ColorDefault = 'black'
myColor(i) = word(myLabelSplit,i*2+1)
myText(i) = word(myLabelSplit,i*2+2)

do for [i=1:strlen(myLabel)] {
    c = strstrt(s,'{/:') # color
    n = strstrt(s,"\n")  # newline
    if (c==0 && n==0) {
        myLabelSplit = myLabelSplit.sprintf('"%s" "%s" "%s" "%s" ', ColorDefault, "", ColorDefault, s)   
        break
    }    # stop if no color or newline is found
    if ((c<n && c>0) || n==0) {
        text = s[:c-1]
        color = word(s[c+3:],1)
        ctext = s[strlen(text)+3+strlen(color)+2:strstrt(s,'}')-1]
        s = s[strlen(text)+3+strlen(color)+strlen(ctext)+3:]
    }
    else {
        text = s[:n-1]
        color = ColorDefault
        ctext = "\n"
        s = s[strlen(text)+2:]
    }
    myLabelSplit = myLabelSplit.sprintf('"%s" "%s" "%s" "%s" ', ColorDefault, text, color, ctext)   
    print myLabelSplit
}
 
# create the labels
PosX = -8
PosY = 8
space = ''
format = '&{%s}%s'
do for [i=0:words(myLabelSplit)/2-1] {
    if (myText(i) eq "\n") {
        format = "\n".format
        space = ''
    } 
    set label sprintf(format,space,myText(i)) at PosX, PosY tc rgb myColor(i) font ",16"
    if (myText(i) ne "\n") { 
        space = space.myText(i)
    }
}

plot x
### end of code

结果: