在matplotlib图例中插入图像 [英] Insert image in matplotlib legend

查看:988
本文介绍了在matplotlib图例中插入图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在maplotlib图的图例中插入几个小图形(矢量图形,但必要时可以制成栅格).图例中每个项目只有一个图形.

I'd like to insert a couple small graphics (vector graphics but can be made raster if necessary) into the legend of a maplotlib plot. There would be one graphic per item in the legend.

我知道我可以使用类似注释框的方式手动绘制整个图例,但是看起来很乏味,并且数字上的任何细微变化都需要手工修复.

I know I could manually draw the entire legend using something like an annotation box but that looks tedious, and any small change in the figure would require fixing it by hand.

在调用pyplot.plot或以后在pyplot.legend调用中,是否可以在标签中包含图形?

Is there any way to include graphics in the label in a call to pyplot.plot or later in the pyplot.legend call?

推荐答案

因此,以下内容有些怪异,但可以帮助您实现大部分目标.注意:您需要用所需的图像替换[PATH TO IMAGE](否则,您将免费获得Grace Hopper!).您还可以通过传递image_stretch参数使图像大于默认图像.这是一种在图像上固定长宽比的怪异方法.如果图像从一个系列到下一个系列重叠,请使用labelspacing参数.

So, the below is a little hacky, but it can get you most of the way there. Note: you need to replace [PATH TO IMAGE] with the image you want (otherwise you get Grace Hopper for free!). You can also make the image larger than the default by passing the image_stretch parameter. This is the hacky way to fix your aspect ratio on the image. Use the labelspacing parameter if your images overlap from one series to the next.

import os

from matplotlib.transforms import TransformedBbox
from matplotlib.image import BboxImage
from matplotlib.legend_handler import HandlerBase
from matplotlib._png import read_png

class ImageHandler(HandlerBase):
    def create_artists(self, legend, orig_handle,
                       xdescent, ydescent, width, height, fontsize,
                       trans):

        # enlarge the image by these margins
        sx, sy = self.image_stretch 

        # create a bounding box to house the image
        bb = Bbox.from_bounds(xdescent - sx,
                              ydescent - sy,
                              width + sx,
                              height + sy)

        tbb = TransformedBbox(bb, trans)
        image = BboxImage(tbb)
        image.set_data(self.image_data)

        self.update_prop(image, orig_handle, legend)

        return [image]

    def set_image(self, image_path, image_stretch=(0, 0)):
        if not os.path.exists(image_path):
            sample = get_sample_data("grace_hopper.png", asfileobj=False)
            self.image_data = read_png(sample)
        else:
            self.image_data = read_png(image_path)

        self.image_stretch = image_stretch

# random data
x = np.random.randn(100)
y = np.random.randn(100)
y2 = np.random.randn(100)

# plot two series of scatter data
s = plt.scatter(x, y, c='b')
s2 = plt.scatter(x, y2, c='r')

# setup the handler instance for the scattered data
custom_handler = ImageHandler()
custom_handler.set_image("[PATH TO IMAGE]",
                         image_stretch=(0, 20)) # this is for grace hopper

# add the legend for the scattered data, mapping the
# scattered points to the custom handler
plt.legend([s, s2],
           ['Scatters 1', 'Scatters 2'],
           handler_map={s: custom_handler, s2: custom_handler},
           labelspacing=2,
           frameon=False)

这是它产生的东西:

这篇关于在matplotlib图例中插入图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆