Matplotlib传奇的增加顺序

时间:2017-02-28 21:27:43

标签: python-3.x matplotlib

我有一个名为5.txt,10.txt,15.txt,20.txt的文本文件但是当我用glob模块读取文件并在图例中使用fname变量时,我得到了无组织的图例数据。

for fname in glob("*.txt"):

    potential, current_density = np.genfromtxt(fname, unpack=True)
    current_density = current_density*1e6
    ax = plt.gca()
    ax.get_yaxis().get_major_formatter().set_useOffset(False)
    plt.plot(potential,current_density, label=fname[0:-4])

plt.legend(loc=4,prop={'size':12}, 
           ncol=1, shadow=True, fancybox=True,
           title = "Scan rate (mV/s)")

enter image description here

如何以递增的顺序绘制数据并为数据提供相应的标签?

3 个答案:

答案 0 :(得分:3)

只是提供另一种方法,不需要在脚本的绘图部分中更改任何内容:

handles, labels = plt.gca().get_legend_handles_labels()
handles, labels = zip(*[ (handles[i], labels[i]) for i in sorted(range(len(handles)), key=lambda k: list(map(int,labels))[k])] )
plt.legend(handles, labels, loc=4, ...)

答案 1 :(得分:2)

方法1(推荐)

您需要自己排序并显示图例。 plt.legend将行列表和字符串列表作为前两个可选位置参数。您可以维护所需项目的列表,按照您想要的顺序对其进行排序,并将您想要的部分传递给legend

ax = plt.gca()
legend_items = []
for fname in glob("*.txt"):
    potential, current_density = np.genfromtxt(fname, unpack=True)
    current_density *= 1e6
    line, = ax.plot(potential, current_density)
    name = fname[0:-4]
    legend_items.append((int(name), line, name))

legend_items.sort()
ax.get_yaxis().get_major_formatter().set_useOffset(False)
ax.legend([x[1] for x in legend_items], [x[2] for x in legend_items],
          loc=4, prop={'size':12},  ncol=1, shadow=True,
          fancybox=True, title = "Scan rate (mV/s)")

主要添加内容以粗体标记,而可能被忽略的次要样式更改标记在斜体中。

主要添加内容包括图例项目的累积。我为每个项目使用元组,因为元组列表首先由第一个元素自动排序。 line, = ax.plot...中的逗号是必需的,因为它会在plot返回的列表中触发参数解包。另一种方法是line = ax.plot(...)[0]。文件名不再作为显式标签添加到数据中。

在较小的更改中,我转而使用ax.plotax.legend代替plt.plotplt.legend。这是Matplotlib API的面向对象部分,它使事情变得更加清晰。此外,您不必一直致电gca()以获取此方式的参考。此外,set_useoffset只需要调用一次,而不是在循环内部。

方法2

解决问题的另一种方法是在处理文件名之前对其进行预排序,以便它们在图例中以正确的顺序显示:

import os
file_list = os.listdir('.')
file_list = [x for x in file_list if x.endswith('.txt')]
file_list.sort(key=lambda x: int(x[0:-4]))
for fname in file_list:
    ...

您必须自己进行名称过滤,但这并不是特别困难。排序键只是数字。此外,您会注意到我厌倦了为此更新执行自定义花式格式化:)

答案 2 :(得分:0)

不知道这是否如此重要,但无论如何我还是到了这里-我发现我不需要中间行-如果您想要2列,这对我有用;

handles, labels = plt.gca().get_legend_handles_labels()
plt.legend(handles, labels, loc=4,
       ncol=2, shadow=True, title="Legend", fancybox=True)