Gnuplot: 在一个字符串列中根据值绘制彩色点,并在图例中显示字符串。

13

我想要绘制分类结果并标记真实类别。基本上,我需要根据字符串列中的值为每个点分配一种颜色。

数据集如下:

5.1 3.5 1.4 0.2 Iris-setosa

我最终采用了以下脚本解决方案(感谢这篇答案:如何在Gnuplot中使点一种颜色当第三列等于零,另一种颜色否则?

set palette model RGB defined (0 "red",1 "blue", 2 "green")
plot 'iris.data' using 1:2:5 notitle with points pt 2 palette

在原始数据集中,我用数字替换了字符串标签,因为我不知道如何在gnuplot中处理字符串。有没有办法将字符串映射到颜色?

目前的输出如下所示: gnuplot coloring points

然而,我不喜欢渐变调色板,因为在这种情况下它没有意义。我更喜欢普通的图例,只有一个颜色和类别的名称。有什么办法可以实现吗?


我有同样的问题。如果gnuplot调色板可以接受字符串而不仅仅是整数,那就太好了。我认为它不行。 - tommy.carstensen
3个回答

6
使用awk是一种可以实现此目的的方法。
使用数据文件Data.csv
5.4452 4.6816 blue
1.2079 9.4082 red
7.4732 6.5507 red
2.3329 8.2996 red
3.4535 2.1937 green
1.7909 2.5173 green
2.5383 7.9700 blue

以及这段脚本:

set pointsize 3
plot "< awk '{if($3 == \"red\") print}' Data.csv" u 1:2 t "red" w p pt 2, \
     "< awk '{if($3 == \"green\") print}' Data.csv" u 1:2 t "green" w p pt 2, \
     "< awk '{if($3 == \"blue\") print}' Data.csv" u 1:2 t "blue" w p pt 2

你将得到这个图:

在此输入图片描述

awk 的作用就是检查数据文件的第三个参数,只有当它具有某些值(比如红色或蓝色)时才打印该行。

您还可以通过去掉渐变调色板来进一步改进脚本。

该脚本可以通过使用 gnuplot 迭代来进一步改进。


谢谢,我对gnuplot还很陌生,语法对我来说相当困惑。使用awk非常方便。 - Tombart
@Tombart 如果你对我在示例中使用的语法有任何具体问题,请告诉我,我会详细解释。 - Woltan
这里的$3是第三列的值,但没有指定分隔符是什么?它会自动被视为<TAB>吗? - damned
@damned 我没有找到任何关于这个的文档,但是看起来你可以使用任意组合的制表符和空格来分隔你的列。也许其他人可以证实一下... - Woltan
我明确地添加了 <TAB> 分隔符,然后它就可以正常工作了:awk -F $'\t' '{if($3 == \"red\") print}' - damned
@damned,在awk中,输入字段分隔符由特殊变量FS定义。默认情况下,它是一个空格,在这种情况下,“字段由空格和/或制表符和/或换行符分隔”。 - user829755

4

将字符串映射到颜色或调色板索引可以在gnuplot中本地完成,关键是使用stringcolumn()和用户定义的映射函数。

以下是使用调色板的示例:

#!/usr/bin/gnuplot -persist

# define a palette with an exact number of colors
set palette maxcolors 3
set palette model RGB defined ( \
  0 "red", \
  1 "blue", \
  2 "green")

# Define palette labels, the range matches the number of colors defined above
set cbrange [0:3]
set cbtics offset 0,+4 ( \
  'color1' 0, \
  'color2' 1, \
  'color3' 2, \
  '' 3)

# define a function to map strings to palette indices
map_color(string) = ( \
  string eq 'color1' ? 0 : \
  string eq 'color2' ? 1 : \
  string eq 'color3' ? 2 : \
  3)

plot '-' using 1:2:(map_color(stringcolumn(3))) notitle with points pt 2 palette
5.4452 4.6816 color1
1.2079 9.4082 color2
7.4732 6.5507 color2
2.3329 8.2996 color2
3.4535 2.1937 color3
1.7909 2.5173 color3
2.5383 7.9700 color1
EOF

enter image description here

可以采用类似的方法直接映射到颜色:
#!/usr/bin/gnuplot -persist

# define a function to map strings to palette indices
map_color(string) = ( \
  string eq 'color1' ? 0xff0000 : \
  string eq 'color2' ? 0x0000ff : \
  string eq 'color3' ? 0x00ff00 : \
  0x000000)

plot '-' using 1:2:(map_color(stringcolumn(3))) notitle with points pt 2 lc rgbcolor variable
5.4452 4.6816 color1
1.2079 9.4082 color2
7.4732 6.5507 color2
2.3329 8.2996 color2
3.4535 2.1937 color3
1.7909 2.5173 color3
2.5383 7.9700 color1
EOF

太棒了,这正是我所需要的!Gnuplot真是太神奇了。只要它不那么难以理解就好了... - Eike P.

3
可以使用调色板来获取任何点的颜色(用于单个点)。
plot file using 1:2:3 with points palette

现在设置一个调色板,以获得所需的颜色比例。您可以设置调色板,例如使用HSV颜色模型计算颜色,或查看gnuplot演示网站上的内容。
只是为了完整起见,请查看gnuplot pm3d colors demo page上的最后一个示例:

color bar with distinct colors in gnuplot

theta(x) = x<0 ? 0 : 1
r(x) = 4*x*(1-theta(x-0.25))
g(x) = 0.5*theta(x-0.25)*(1-theta(x-0.5))
b(x) = x
set palette model RGB functions r(gray),g(gray),b(gray)
set title "set palette model RGB functions\n4*x*(1-theta(x-0.25)), 0.5*theta(x-0.25)*(1-theta(x-0.5)), x"
splot f(x)enter code here

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接