matplotlib从起点出发(8)_Tutorial_8_Legend

1 图例教程

在matplotlib中灵活地生成Legend。

本图例指南是legend()中可用文档的扩展——在继续阅读本指南之前,请确保你熟悉legend()文档的内容。

本指南使用了一些常用术语,为清楚起见,此处记录了这些术语:

  • legend entry
    图例由一个或多个图例entry(条目)组成。entry(条目)仅由一个键和一个标签组成。

  • legend key
    每个图例标签左侧的彩色/图案标记。

  • legend label
    描述由键表示的句柄的文本。

  • legend handle
    用于在图例中生成相应条目的原始对象。

2 控制图例的条目

调用不带参数的legend()会自动获取图例句柄及其关联的标签。此功能等效于:

handles, labels = ax.get_legend_handles_labels()
ax.legend(handles, labels)

get_legend_handles_labels()函数返回轴上存在的句柄/artist列表,可用于为生成的图例生成条目——值得注意的是,并非所有的artist都可以添加到图例中,此时必须创建一个“代理”(请参阅创建专门用于添加到图例的artist,又名代理artist,以获取更多详细信息。)

注意
将忽略以空字符串作为标签或标签以下划线“_”开头的artist。

为了完全控制要添加到图例的内容,通常将适当的句柄直接传递给legend():

fig, ax = plt.subplots()
line_up, = ax.plot([1, 2, 3], label='Line 2')
line_down, = ax.plot([3, 2, 1], label='Line 1')
ax.legend(handles=[line_up, line_down])

在某些情况下,无法设置句柄的标签,因此可以将标签列表传递给legend()

fig, ax = plt.subplots()
line_up, = ax.plot([1, 2, 3], label='Line 2')
line_down, = ax.plot([3, 2, 1], label='Line 1')
ax.legend([line_up, line_down], ['Line Up', 'Line Down'])

3 创建专门用于添加到legend的artist(代理artist)

并非所有句柄都可以自动转换为图例条目,因此通常需要创建一个可以的artist。图例句柄不必存在于Figure或Axes上即可使用。

假设我们想创建一个图例,其中包含一些由红色表示的数据条目:

import matplotlib.patches as mpatches
import matplotlib.pyplot as pltfig, ax = plt.subplots()
red_patch = mpatches.Patch(color='red', label='The red data')
ax.legend(handles=[red_patch])plt.show()

在这里插入图片描述

有许多受支持的图例句柄。我们可以创建一条带有标记的线,而不是创建色块:

import matplotlib.lines as mlinesfig, ax = plt.subplots()
blue_line = mlines.Line2D([], [], color='blue', marker='*',markersize=15, label='Blue stars')
ax.legend(handles=[blue_line])plt.show()

在这里插入图片描述

如图,图例换成了一条带有蓝色星星的线。

3 图例位置

图例的位置可以通过关键字参数loc进行指定。有关更多详细信息,请参阅legend()中的文档。

bbox_to_anchor关键字为手动图例放置提供了很大程度的控制。例如,如果你希望axes图例位于图形的右上角而不是axes的角,只需指定角的位置和该位置的坐标系:

ax.legend(bbox_to_anchor=(1, 1),bbox_transform=fig.transFigure)

自定义图例放置的更多示例:

fig, ax_dict = plt.subplot_mosaic([['top', 'top'], ['bottom', 'BLANK']],empty_sentinel="BLANK")
ax_dict['top'].plot([1, 2, 3], label="test1")
ax_dict['top'].plot([3, 2, 1], label="test2")
# Place a legend above this subplot, expanding itself to
# fully use the given bounding box.
ax_dict['top'].legend(bbox_to_anchor=(0., 1.02, 1., .102), loc='lower left',ncols=2, mode="expand", borderaxespad=0.)ax_dict['bottom'].plot([1, 2, 3], label="test1")
ax_dict['bottom'].plot([3, 2, 1], label="test2")
# Place a legend to the right of this smaller subplot.
ax_dict['bottom'].legend(bbox_to_anchor=(1.05, 1),loc='upper left', borderaxespad=0.)

在这里插入图片描述

Figure的图例

有时,相对于(子)图形而不是单个Axes来放置图例会更有意义。通过使用constrained_layout并在loc关键字参数的开头指定外部,图例将绘制在(子)图的Axes区域之外。

fig, axs = plt.subplot_mosaic([['left', 'right']], layout='constrained')axs['left'].plot([1, 2, 3], label="test1")
axs['left'].plot([3, 2, 1], label="test2")axs['right'].plot([1, 2, 3], 'C2', label="test3")
axs['right'].plot([3, 2, 1], 'C3', label="test4")
# Place a legend to the right of this smaller subplot.
fig.legend(loc='outside upper right')

在这里插入图片描述

这里接收的语法与普通loc关键字略有不同,其中“外右上”与“外上右”不同。
在这里插入图片描述

在这里插入图片描述

4 同一Axes上的多个图例

有时,将图例条目拆分到 多个图例中会更清晰。虽然这样做的一个基本方法可能是多次调用legend()函数,但你会发现Axes上只存在一个图例。这样做是为了可以重复调用legend()以将图例更新到 Axes上的最新句柄。要保留旧的图例实例,我们必须手动将它们添加到 Axes 中:

fig, ax = plt.subplots()
line1, = ax.plot([1, 2, 3], label="Line 1", linestyle='--')
line2, = ax.plot([3, 2, 1], label="Line 2", linewidth=4)# Create a legend for the first line.
first_legend = ax.legend(handles=[line1], loc='upper right')# Add the legend manually to the Axes.
ax.add_artist(first_legend)# Create another legend for the second line.
ax.legend(handles=[line2], loc='lower right')plt.show()

在这里插入图片描述

5 图例句柄

为了创建图例条目,句柄作为参数提供给相应的HandlerBase子类。处理程序子类的选择由以下规则确定:

  1. 使用handler_map关键字中的值更新get_legend_handler_map();
  2. 检查句柄是否在新创建的handler_map中;
  3. 检查句柄的类型是否在新创建的handler_map中;
  4. 检查句柄的mro中的任何类型是否位于新创建的handler_map中。

为了完整起见,此逻辑主要在get_legend_handler()中实现。

所有这些灵活性意味着我们有必要的钩子来为我们自己的图例键类型实现自定义处理程序。

使用自定义处理程序的最简单示例是实例化现有legend_handler之一。处理程序库子类。为了简单起见,让我们选择legend_handlerHandlerLine2D接受numpoints参数(为了方便起见,numpoints也是legend()函数上的关键字)。然后,我们可以将实例到Handler的映射作为图例的关键字传递。

from matplotlib.legend_handler import HandlerLine2Dfig, ax = plt.subplots()
line1, = ax.plot([3, 2, 1], marker='o', label='Line 1')
line2, = ax.plot([1, 2, 3], marker='o', label='Line 2')ax.legend(handler_map={line1: HandlerLine2D(numpoints=4)})

在这里插入图片描述

如你所见,“第1行”现在有4个标记点,其中“第2行”有2个(默认值)。尝试上面的代码,只将map的键从第1行更改为type(第1行)。请注意,现在两个Line2D实例都有4个标记。

除了复杂给力类型(如误差图、词干图和直方图)的处理程序外,默认handler_map还有一个特殊的元组处理程序(legend_handler.HandlerTuple),它只是将给定元组中的每个项目的句柄绘制在彼此之上。以下示例演示了将两个图例键相互叠加的组合:

from numpy.random import randnz = randn(10)fig, ax = plt.subplots()
red_dot, = ax.plot(z, "ro", markersize=15)
# Put a white cross over some of the data.
white_cross, = ax.plot(z[:5], "w+", markeredgewidth=3, markersize=15)ax.legend([red_dot, (red_dot, white_cross)], ["Attr A", "Attr A+B"])

在这里插入图片描述

legend_handler.HandlerTuple类还可用于将多个图例键分配给同一条目:

from matplotlib.legend_handler import HandlerLine2D, HandlerTuplefig, ax = plt.subplots()
p1, = ax.plot([1, 2.5, 3], 'r-d')
p2, = ax.plot([3, 2, 1], 'k-o')l = ax.legend([(p1, p2)], ['Two keys'], numpoints=1,handler_map={tuple: HandlerTuple(ndivide=None)})

在这里插入图片描述

实现自定义图例处理程序

可以实现自定义处理程序以将任何句柄转换为图例键(句柄不一定需要是matplotlib artist)。处理程序必须实现一个legend_artist方法,该方法返回单 个artist供图例使用。legend_artist所需的签名记录在legend_artist的文档中。

import matplotlib.patches as mpatchesclass AnyObject:passclass AnyObjectHandler:def legend_artist(self, legend, orig_handle, fontsize, handlebox):x0, y0 = handlebox.xdescent, handlebox.ydescentwidth, height = handlebox.width, handlebox.heightpatch = mpatches.Rectangle([x0, y0], width, height, facecolor='red',edgecolor='black', hatch='xx', lw=3,transform=handlebox.get_transform())handlebox.add_artist(patch)return patchfig, ax = plt.subplots()ax.legend([AnyObject()], ['My first handler'],handler_map={AnyObject: AnyObjectHandler()})

在这里插入图片描述

或者,如果我们想全局接受AnyObject实例,而不需要一直手动设置handler_map关键字,我们可以注册新的处理程序:

from matplotlib.legend import Legend
Legend.update_default_handler_map({AnyObject: AnyObjectHandler()})

虽然这里的力量是显而易见的,但请记住,已经实现了许多处理程序,并且你想要实现的目标可能已经可以通过现有类轻松实现。例如,要生成椭圆图例键,而不是矩形图例键:

from matplotlib.legend_handler import HandlerPatchclass HandlerEllipse(HandlerPatch):def create_artists(self, legend, orig_handle,xdescent, ydescent, width, height, fontsize, trans):center = 0.5 * width - 0.5 * xdescent, 0.5 * height - 0.5 * ydescentp = mpatches.Ellipse(xy=center, width=width + xdescent,height=height + ydescent)self.update_prop(p, orig_handle, legend)p.set_transform(trans)return [p]c = mpatches.Circle((0.5, 0.5), 0.25, facecolor="green",edgecolor="red", linewidth=3)fig, ax = plt.subplots()ax.add_patch(c)
ax.legend([c], ["An ellipse, not a rectangle"],handler_map={mpatches.Circle: HandlerEllipse()})

在这里插入图片描述

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/104135.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python批处理(一)提取txt中数据存入excel

Python批处理(一)提取txt中数据存入excel 问题描述 现从冠层分析软件中保存了叶面积指数分析的结果,然而软件保存格式为txt,且在不同的文件夹中,每个文件夹的txt文件数量不固定,但是txt文件格式固定。现需…

【MySQL】基础语法总结

MySQL 基础语句 一、DDL 数据库定义语言 1.1CREATE 创建 1.1.1 创建数据库 语法结构 CREATE DATABASE database_name;示例 CREATE DATABASE demo;1.1.2 创建表 语法结构 CREATE TABLE 表名 (列1 数据类型,列2 数据类型,... );示例 CREATE TABLE new_user (id INT PRIMARY KE…

【strstr函数的介绍和模拟实现——超详细版】

strstr函数的介绍和模拟实现 strstr函数的介绍 资源来源于cplusplus网站 strstr函数声明: char *strstr( const char *str1, const char *str2 ); 它的作用其实就是: 在字符串str1中查找是否含有字符串str2,如果存在,返回str2在…

go-zero直连与etcd服务注册中心

go-zero中直连方式 在使用grpc是最重要的就是pb文件了,生成的pb文件,通过pb文件可以生成grpc的客户端和服务端,那么客户端和服务端就可以直连了,再次基础上可以引入etcd实现服务注册。 所有的代码都需要开发者编写,包…

7 个适合初学者的项目,可帮助您开始使用 ChatGPT

推荐:使用 NSDT场景编辑器快速搭建3D应用场景 从自动化日常任务到预测复杂模式,人工智能正在重塑行业并重新定义可能性。 当我们站在这场人工智能革命中时,我们必须了解它的潜力并将其整合到我们的日常工作流程中。 然而。。。我知道开始使…

企业架构LNMP学习笔记21

URL重写: ngx_http_rewrite_module 模块用于使用PCRE正则表达式更改请求URI,返回重定向,以及有条件地选择配置。 return 该指令用于结束结束规则的执行并返回状态码给客户端。 403 Forbidden.服务器已经理解请求,但是拒绝执行它 404 Not…

音频——I2S DSP 模式(五)

I2S 基本概念飞利浦(I2S)标准模式左(MSB)对齐标准模式右(LSB)对齐标准模式DSP 模式TDM 模式 文章目录 DSP formatDSP A时序图逻辑分析仪抓包 DSP B时序图逻辑分析仪抓包 DSP format DSP/PCMmode 分为 Mode-A 和 Mode-B 共 2 种模式。不同芯⽚有的称为 PCM mode 有的称为 DSP m…

ms17-010(永恒之蓝)漏洞复现

目录 前言 一、了解渗透测试流程 二、使用nmap工具对win7进行扫描 2.1 2.2 2.3 2.4 2.5 三、尝试ms17-010漏洞利用 3.1 3.2 3.3 3.4 3.5 3.6 3.7 3.8 3.9 3.10 3.11 四、结果展示 4.1 4.2 4.3 4.4 4.5 总结 前言 ms17-010(永恒之蓝&am…

说说分布式系统容器化

继上一篇浅谈高并发分布式架构演进路径,单体服务完成分布式架构改造,转型为微服务。随着微服务数量的急剧增加,跨应用、跨系统的调用越来越多,调用关系和依赖关系日益复杂,这种复杂性增加了系统的设计、实施和维护的难…

【精品】NLP自然语言处理学习路线(知识体系)

当前,大规模预训练语言模型的强大对话问答、文本生成能力,将自然语言处理(NLP)的研究和应用推向了新一轮的热潮。NLP是计算机科学、人工智能和语言学等学科交叉的前沿领域。NLP的应用和研究范围非常的广泛,个人是没有找…

群晖NAS教程(二十四)、利用ContainerManager安装jellyfin

群晖NAS教程(二十四)、利用ContainerManager安装jellyfin 一、下载nyamisaka/jellyfin镜像 二、运行jellyfin容器并配置 容器名称可以随便填写 这里映射端口设置为8096,并且映射了两个配置文件夹和一个电影的目录。 点击完成。 这里看到已经运行起来了。 三、jelly…

Vue项目案例-头条新闻

目录 1.项目介绍 1.1项目功能 1.2数据接口 1.3设计思路 2.创建项目并安装依赖 2.1创建步骤 2.2工程目录结构 2.3配置文件代码 3.App主组件开发 3.1设计思路 3.2对应代码 4.共通组件开发 4.1设计思路 4.2对应代码 5.头条新闻组件开发 5.1设计思路 5.2对应代码 …