Replace Matplotlib legend's labels with image

前端 未结 1 1547
梦如初夏
梦如初夏 2020-12-11 08:45

I would like to use image instead of labels in the legend.

For example, I draw 2 lines and show a legend :

import matplotlib.pyplot as plt
plt.plot([         


        
相关标签:
1条回答
  • 2020-12-11 08:57

    The concept for creating an image in a legend is already presented in this question (Insert image in matplotlib legend) where an image is used as an artist for a legend entry.

    In case you want a line handle and an image in the legend, the idea would be to create a handle that consists of both of them, positionned next to each other. The only problem is then to fine tune the parameters such that this looks appealing.

    import matplotlib.pyplot as plt
    import matplotlib.lines
    from matplotlib.transforms import Bbox, TransformedBbox
    from matplotlib.legend_handler import HandlerBase
    from matplotlib.image import BboxImage
    
    class HandlerLineImage(HandlerBase):
    
        def __init__(self, path, space=15, offset = 10 ):
            self.space=space
            self.offset=offset
            self.image_data = plt.imread(path)        
            super(HandlerLineImage, self).__init__()
    
        def create_artists(self, legend, orig_handle,
                           xdescent, ydescent, width, height, fontsize, trans):
    
            l = matplotlib.lines.Line2D([xdescent+self.offset,xdescent+(width-self.space)/3.+self.offset],
                                         [ydescent+height/2., ydescent+height/2.])
            l.update_from(orig_handle)
            l.set_clip_on(False)
            l.set_transform(trans)
    
            bb = Bbox.from_bounds(xdescent +(width+self.space)/3.+self.offset,
                                  ydescent,
                                  height*self.image_data.shape[1]/self.image_data.shape[0],
                                  height)
    
            tbb = TransformedBbox(bb, trans)
            image = BboxImage(tbb)
            image.set_data(self.image_data)
    
            self.update_prop(image, orig_handle, legend)
            return [l,image]
    
    
    plt.figure(figsize=(4.8,3.2))
    line,  = plt.plot([1,2],[1.5,3], color="#1f66e0", lw=1.3)
    line2,  = plt.plot([1,2],[1,2], color="#efe400", lw=1.3)
    plt.ylabel("Flower power")
    
    plt.legend([line, line2], ["", ""],
       handler_map={ line: HandlerLineImage("icon1.png"), line2: HandlerLineImage("icon2.png")}, 
       handlelength=2, labelspacing=0.0, fontsize=36, borderpad=0.15, loc=2, 
        handletextpad=0.2, borderaxespad=0.15)
    
    plt.show()
    

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