Replace Matplotlib legend's labels with image

和自甴很熟 提交于 2019-12-17 20:25:30

问题


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,2],label="first_image")
plt.plot([2,1],label="second_image")
plt.legend()
plot.show()

But I would like to have something like this :

Note that this is not a duplicate of Insert image in matplotlib legend , My issue is "change the label into an image", while the other is "change the legend's symbol into an image"


回答1:


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()



来源:https://stackoverflow.com/questions/42155119/replace-matplotlib-legends-labels-with-image

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!