Stop matplotlib repeating labels in legend

前端 未结 6 1598
逝去的感伤
逝去的感伤 2020-11-28 23:03

Here is a very simplified example:

xvalues = [2,3,4,6]

for x in xvalues:
    plt.axvline(x,color=\'b\',label=\'xvalues\')

plt.legend()

Th

6条回答
  •  广开言路
    2020-11-28 23:49

    Problem - 3D Array

    Questions: Nov 2012, Oct 2013

    import numpy as np
    a = np.random.random((2, 100, 4))
    b = np.random.random((2, 100, 4))
    c = np.random.random((2, 100, 4))
    

    Solution - dict uniqueness

    For my case _nolegend_ (bli and DSM) would not work, nor would label if i==0. ecatmur's answer uses get_legend_handles_labels and reduces the legend down with collections.OrderedDict. Fons demonstrates this is possible without an import.

    Inline with these answers, I suggest using dict for unique labels.

    # Step-by-step
    ax = plt.gca()                      # Get the axes you need
    a = ax.get_legend_handles_labels()  # a = [(h1 ... h2) (l1 ... l2)]  non unique
    b = {l:h for h,l in zip(*a)}        # b = {l1:h1, l2:h2}             unique
    c = [*zip(*b.items())]              # c = [(l1 l2) (h1 h2)]
    d = c[::-1]                         # d = [(h1 h2) (l1 l2)]
    plt.legend(*d)
    

    Or

    plt.legend(*[*zip(*{l:h for h,l in zip(*ax.get_legend_handles_labels())}.items())][::-1])
    

    Maybe less legible and memorable than Matthew Bourque's solution. Code golf welcome.

    Example

    import numpy as np
    a = np.random.random((2, 100, 4))
    b = np.random.random((2, 100, 4))
    
    import matplotlib.pyplot as plt
    fig, ax = plt.subplots(1)
    ax.plot(*a, 'C0', label='a')
    ax.plot(*b, 'C1', label='b')
    
    ax.legend(*[*zip(*{l:h for h,l in zip(*ax.get_legend_handles_labels())}.items())][::-1])
    # ax.legend()   # Old,  ^ New
    
    plt.show()
    

提交回复
热议问题