我怀疑您能否提出仅 gnuplot 的解决方案。但是,只要您的系统上安装了 python2.5 或更新版本,这应该可以工作。(它适用于您的测试数据)。
import sys
import collections
data = collections.defaultdict(list)
keys = []
# build a mapping which maps values to xticlabels (hereafter "keys")
# Keep a second keys list so we can figure out the order we put things into
# the mapping (dict)
with open(sys.argv[1]) as f:
for line in f:
key,value = line.split()
data[key.strip()].append( value )
keys.append(key.strip())
def unique(seq):
"""
Simple function to make a sequence unique while preserving order.
Returns a list
"""
seen = set()
seen_add = seen.add
return [ x for x in seq if x not in seen and not seen_add(x) ]
keys = unique(keys) #make keys unique
#write the keys alongside 1 element from the corresponding list.
for k in keys:
sys.stdout.write( '%s %s\n' % (k, data[k].pop()) )
# Two blank lines tells gnuplot the following is another dataset
sys.stdout.write('\n\n')
# Write the remaining data lists in order assigning x-values
# for each list (starting at 0 and incrementing every time we get
# a new key)
for i,k in enumerate(keys):
v = data[k]
for item in v:
sys.stdout.write( '%d %s\n' % (i, item) )
现在绘制这个的脚本:
set style line 1 lt 1 pt 1
plot '<python pythonscript.py data' i 0 u 2:xticlabels(1) ls 1,\
'' i 1 u 1:2 ls 1 notitle
这是它的工作原理。当您执行类似的操作时plot ... u 2:xticlabels(1)
,gnuplot会隐式地将顺序整数 x 值分配给数据点(从 0 开始)。python 脚本重新排列数据以利用这一事实。基本上,我创建了一个映射,它将第一列中的“键”映射到与该键对应的元素列表。换句话说,在您的虚拟数据文件中,键'a'
映射到值列表[10.1, 3.2]
. 但是,python 字典(映射)没有排序。因此,我保留了第二个列表来维护顺序(例如,将轴标记为“a”、“b”、“c”而不是“c”、“a”、“b”)。我确保轴列表是唯一的,以便我可以使用它来打印必要的数据。我在 2 遍中写入数据。第一遍仅打印每个列表中的一个值以及映射“键”。第二遍打印其余的值以及 gnuplot 将隐式分配给它们的 x 值。在两个数据集之间,我插入了 2 个空行,以便 gnuplot 可以使用index
关键字(这里缩写为i
)。现在我们只需要相应地绘制两个数据集。首先,我们设置了一个线型,以便两个通道在绘制时具有相同的样式。然后我们用 xticlabels 和索引 1 绘制索引 0(第一个数据集),使用 python 脚本计算的 x 值、y 值对 ( u 1:2
)。抱歉,解释很长(并且原始版本有些错误)。祝你好运,快乐的 gnuplotting!