pyplot在图例中组合了多个线条标签

时间:2014-10-13 10:10:53

标签: python matplotlib plot legend

我有数据会导致多行被绘制,我想在这个行中为这些行添加一个标签。我认为使用下面的例子可以更好地证明这一点,

a = np.array([[ 3.57,  1.76,  7.42,  6.52],
              [ 1.57,  1.2 ,  3.02,  6.88],
              [ 2.23,  4.86,  5.12,  2.81],
              [ 4.48,  1.38,  2.14,  0.86],
              [ 6.68,  1.72,  8.56,  3.23]])

plt.plot(a[:,::2].T, a[:, 1::2].T, 'r', label='data_a')

plt.legend(loc='best')

正如您在Out [23]中所看到的,该情节产生了5条不同的线条。结果情节看起来像这样 legend of multiple line plot

有什么方法可以告诉绘图方法避免多个标签?我不想使用自定义图例(您可以同时指定标签和线条形状)。

8 个答案:

答案 0 :(得分:10)

如果我打算经常这样做,我会亲自制作一个小帮手功能;

from matplotlib import pyplot
import numpy


a = numpy.array([[ 3.57,  1.76,  7.42,  6.52],
                 [ 1.57,  1.2 ,  3.02,  6.88],
                 [ 2.23,  4.86,  5.12,  2.81],
                 [ 4.48,  1.38,  2.14,  0.86],
                 [ 6.68,  1.72,  8.56,  3.23]])


def plotCollection(ax, xs, ys, *args, **kwargs):

  ax.plot(xs,ys, *args, **kwargs)

  if "label" in kwargs.keys():

    #remove duplicates
    handles, labels = pyplot.gca().get_legend_handles_labels()
    newLabels, newHandles = [], []
    for handle, label in zip(handles, labels):
      if label not in newLabels:
        newLabels.append(label)
        newHandles.append(handle)

    pyplot.legend(newHandles, newLabels)

ax = pyplot.subplot(1,1,1)  
plotCollection(ax, a[:,::2].T, a[:, 1::2].T, 'r', label='data_a')
plotCollection(ax, a[:,1::2].T, a[:, ::2].T, 'b', label='data_b')
pyplot.show()

从图例的handleslabels中删除重复项(比您拥有的)更简单(和IMO更清晰)的方法是:

handles, labels = pyplot.gca().get_legend_handles_labels()
newLabels, newHandles = [], []
for handle, label in zip(handles, labels):
  if label not in newLabels:
    newLabels.append(label)
    newHandles.append(handle)
pyplot.legend(newHandles, newLabels)

答案 1 :(得分:6)

因此,使用意见建议和另一个问题here,我将在此处留下补救措施

handles, labels = plt.gca().get_legend_handles_labels()
i =1
while i<len(labels):
    if labels[i] in labels[:i]:
        del(labels[i])
        del(handles[i])
    else:
        i +=1

plt.legend(handles, labels)

新的情节看起来像, modified multiple line plot legend

答案 2 :(得分:6)

Numpy解决方案基于上述意愿的回应。

import numpy as np
import matplotlib.pylab as plt
a = np.array([[3.57, 1.76, 7.42, 6.52],
              [1.57, 1.20, 3.02, 6.88],
              [2.23, 4.86, 5.12, 2.81],
              [4.48, 1.38, 2.14, 0.86],
              [6.68, 1.72, 8.56, 3.23]])

plt.plot(a[:,::2].T, a[:, 1::2].T, 'r', label='data_a')
handles, labels = plt.gca().get_legend_handles_labels()

假设等标签具有相同的句柄,则获取唯一标签及其各自的索引,这些索引对应于句柄索引。

labels, ids = np.unique(labels, return_index=True)
handles = [handles[i] for i in ids]
plt.legend(handles, labels, loc='best')
plt.show()

答案 3 :(得分:5)

Matplotlib为行集合LineCollection提供了一个很好的界面。代码很简单

> dput(dt)
structure(list(Chromosome = structure(c(1L, 1L, 1L, 1L, 2L, 2L, 
2L, 2L, 2L), .Label = c("chr1", "chr2"), class = "factor"), Start = c(0L, 
8022945L, 9168284L, 9598904L, 0L, 8022930L, 9168284L, 9598904L, 
31392788L), End = c(8022945L, 9168284L, 9598904L, 31392788L, 
8022930L, 9168284L, 9598904L, 31392788L, 35402000L), lengthMB = c(8.023, 
1.145, 0.431, 21.794, 8.023, 1.145, 0.431, 21.794, 1.164), imba = c(0.026905119, 
0.030441784, NA, 0.036011994, 0.026905119, 0.030441784, NA, 0.036011994, 
0.029733771), log2 = c(-0.001671481, 0.000601976, -0.024952441, 
0.002151497, -0.001671481, 0.000601976, -0.024952441, 0.002151497, 
0.003149921), Cn = c(2L, 2L, 2L, 3L, 3L, 2L, 2L, 2L, 2L), mCn = c(1L, 
1L, 1L, 1L, 1L, 1L, 1L, 0L, 1L), Cn_ = c(1.99, 2, 1.91, 3.01, 
2.89, 1.87, 1.57, 1.87, 2.01)), .Names = c("Chromosome", "Start", 
"End", "lengthMB", "imba", "log2", "Cn", "mCn", "Cn_"), class = c("data.table", 
"data.frame"), row.names = c(NA, -9L), .internal.selfref = <pointer: 0x26abf68>)

这导致以下输出: A plot of the lines collected under a single legend entry.

答案 4 :(得分:1)

我会做到这一点:

for i in range(len(a)):
  plt.plot(a[i,::2].T, a[i, 1::2].T, 'r', label='data_a' if i==0 else None)

答案 5 :(得分:0)

低技术解决方案是进行两次情节调用。一个绘制你的数据,另一个绘制任何东西但只带有句柄:

a = np.array([[ 3.57,  1.76,  7.42,  6.52],
              [ 1.57,  1.2 ,  3.02,  6.88],
              [ 2.23,  4.86,  5.12,  2.81],
              [ 4.48,  1.38,  2.14,  0.86],
              [ 6.68,  1.72,  8.56,  3.23]])

plt.plot(a[:,::2].T, a[:, 1::2].T, 'r')
plt.plot([],[], 'r', label='data_a')

plt.legend(loc='best')

结果如下:

result

答案 6 :(得分:0)

删除重复项的最简单和最 Pythonic 的方法是使用 dict 的键,这些键保证是唯一的。这也确保我们只对每个 (handle, label) 对迭代一次。

handles, labels = plt.gca().get_legend_handles_labels()

# labels will be the keys of the dict, handles will be values
temp = {k:v for k,v in zip(labels, handles)}

plt.legend(temp.values(), temp.keys(), loc='best')

答案 7 :(得分:0)

我找到了解决这个问题的捷径:

a = np.array([[ 3.57,  1.76,  7.42,  6.52],
              [ 1.57,  1.2 ,  3.02,  6.88],
              [ 2.23,  4.86,  5.12,  2.81],
              [ 4.48,  1.38,  2.14,  0.86],
              [ 6.68,  1.72,  8.56,  3.23]])

p1=plt.plot(a[:,::2].T, a[:, 1::2].T, color='r')
plt.legend([p1[0]],['data_a'],loc='best')