Completely custom legend in Matplotlib, Python

前端 未结 2 661
悲&欢浪女
悲&欢浪女 2021-01-02 17:18

I am using Matplotlib to basically draw a \'picture\', not for plotting data.

In the \'picture\' I use plt.annotate to label certain parts of the pictur

相关标签:
2条回答
  • 2021-01-02 17:26

    In most cases you probably also want to illustrate elements on the graphic with color in your custom legend. In this case I would simply use matplotlib's own functions, than you also do not need to write your own complex function.

    import matplotlib 
    
    red_line = matplotlib.lines.Line2D([], [], color='red',markersize=100, label='Blue line')
    
    
    blue_line = matplotlib.lines.Line2D([], [], color='blue', markersize=100, label='Green line')
    purple_line = matplotlib.lines.Line2D([], [], color='purple', markersize=100, label='Green line')
    
    handles = [blue_line,red_line, purple_line]
    labels = [h.get_label() for h in handles] 
    
    ax.legend(handles=handles, labels=labels)  
    plt.show()
    
    0 讨论(0)
  • 2021-01-02 17:35

    There are a lot of ways to do it, but it's probably easiest to use a proxy artist in this case. You can use arbitrary text as a marker, so it's fairly easy to have fake Line2D's show labels instead of lines.

    As an example (the bulk of this is the relatively "fancy" call to annotate):

    import numpy as np
    import matplotlib
    import matplotlib.pyplot as plt
    
    def main():
        labels = ['A', 'B', 'C']
        positions = [(2, 5), (1, 1), (4, 8)]
        descriptions = ['Happy Cow', 'Sad Horse', 'Drooling Dog']
    
        # Plot the data, similar to what you described...
        fig, ax = plt.subplots()
        ax.imshow(np.random.random((10, 10)), interpolation='none')
        for label, xy in zip(labels, positions):
            ax.annotate(label, xy, xytext=(20, 20), size=15,
                        textcoords='offset points',
                        bbox={'facecolor':'white'},
                        arrowprops={'arrowstyle':'->'})
    
        # Create a legend with only labels
        proxies = [create_proxy(item) for item in labels]
        ax.legend(proxies, descriptions, numpoints=1, markerscale=2)
    
        plt.show()
    
    def create_proxy(label):
        line = matplotlib.lines.Line2D([0], [0], linestyle='none', mfc='black',
                    mec='none', marker=r'$\mathregular{{{}}}$'.format(label))
        return line
    
    main()
    

    enter image description here

    0 讨论(0)
提交回复
热议问题