matplotlib图例使用案例1.1:在不同行或列的图例上添加title

news2025/1/20 1:56:00

我们将图例进行行显示或者列显示后,只能想继续赋予不同行或者列不同的title来进行分类。比较简单的方式,就是通过ax.annotate方法添加标签,这样方法复用率比较低,每次使用都要微调ax.annotate的显示位置。比较方便的方法是在案例1实现的基础上,添加title显示的功能。

motplotlib图例案例1:通过多个legend完全控制图例显示顺序(指定按行排序 or 按列排序)

添加title显示功能后的代码:

import matplotlib.pyplot as plt
import matplotlib.axes
from typing import List, Tuple, Any
#这个函数可以获得axis对象的已经绘制的artist中的所有的hander和labels,这个可以只给它一个axis参数。注意这个参数需要是列表类的。
from matplotlib.legend import _get_legend_handles_labels as get_legend_handles_labels

def custom_legend_layout(axis: matplotlib.axes.Axes,
                         handlers: List[Any]=None,
                         labels: List[str]=None,
                         n_items: int = 3,
                         offset: float = 0.05,
                         vertical: bool = False,
                         loc: str = 'upper right',
                         first_bbox_to_anchor: Tuple[float, float] = (1, 1),
                         title:List[str]=None,
                         title_shift:List[Tuple[float,float]]=None,
                         **kwargs) -> None:
    """
    A function to arrange legend items in a custom layout.

    :param axis: Axis object on which to place the legends.
    :param lines: List of line objects to include in the legends.
    :param labels: List of labels corresponding to the line objects.
    :param n_items: Number of items per row (if vertical=False) or column (if vertical=True).
    :param offset: Vertical offset between rows (or horizontal offset between columns if vertical=True).
    :param vertical: If True, legends are arranged vertically, otherwise horizontally.
    :param loc: Location anchor for all legends.
    :param first_bbox_to_anchor:  `~matplotlib.transforms.BboxBase` instance,Bbox anchor of the first legend.
    :param kwargs: Additional keyword arguments to pass to the legend function.
    """
    va_dict={
        "center":'center',
        "lower":'top',
        "upper":'bottom'
    }

    ha_dict={
        "center": 'center',
        "right":"left",
        "left":"right",
    }

    if (handlers is None) != (labels is None):  # Check if only one of handlers or labels is provided
        raise ValueError("Both 'handlers' and 'labels' must be specified if one is provided.")

    if (handlers is None) and (labels is None): # get default handlers and labels from ax
        handlers,labels=get_legend_handles_labels(axs=[axis]) # note:  the param axs is list object

    # 确保n_items不为0,避免除以0的错误
    n_items = max(1, n_items)
    # 计算需要多少个图例
    n_legends = len(handlers) // n_items + (1 if len(handlers) % n_items else 0)

    # 计算每个图例的bbox_to_anchor
    for i in range(n_legends):
        start_idx = i * n_items
        end_idx = min(start_idx + n_items, len(handlers))
        legend_lines = handlers[start_idx:end_idx]
        legend_labels = labels[start_idx:end_idx]

        if vertical:
            # 对于垂直布局
            ncol = 1
            if i == 0:
                bbox_anchor = first_bbox_to_anchor
            else:
                # 计算后续图例的bbox_to_anchor
                bbox_anchor = (first_bbox_to_anchor[0] + i * offset, first_bbox_to_anchor[1])
        else:
            # 对于水平布局
            ncol = len(legend_lines)
            if i == 0:
                bbox_anchor = first_bbox_to_anchor
            else:
                # 计算后续图例的bbox_to_anchor
                bbox_anchor = (first_bbox_to_anchor[0], first_bbox_to_anchor[1] - i * offset)

        legend = axis.legend(legend_lines, legend_labels, loc=loc, bbox_to_anchor=bbox_anchor, ncol=ncol, frameon=False, **kwargs)
        axis.add_artist(legend)
        # 计算每个title的位置
        va_key,ha_key=loc.split(" ")
        if title and len(title)==n_legends:

            w_shift= title_shift[i][0] if title_shift else 0
            h_shift=title_shift[i][1] if title_shift else 0

            axis.annotate(
                text=title[i],
                xy=(bbox_anchor[0]+w_shift, bbox_anchor[1]+h_shift),
            xycoords='axes fraction',
            va=va_dict[va_key],
            ha=ha_dict[ha_key]
            )

if __name__ == '__main__':


    # 示例使用这个函数
    fig, ax = plt.subplots()
    handlers = [ax.scatter(range(10), [i * x for x in range(10)], label=f'Line {i}') for i in range(7)]

    # 调用函数,横向排列图例
    custom_legend_layout(ax, n_items=3, offset=0.25, vertical=True,
                         loc='upper left', first_bbox_to_anchor=(0.2, 0.8),
                         title=["title 1","title 2","title 3"],
                         #title_shift=[(-0.1,0),(-0.1,0),(-0.1,0)],
                         )


    from matplotlib.legend import _get_legend_handles_labels as get_legend_handles_labels

    handles,labels=get_legend_handles_labels([ax])

    plt.show()

运行后:

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

PyTorch使用Tricks:Dropout,R-Dropout和Multi-Sample Dropout等 !!

文章目录 1、为什么使用Dropout? 2、Dropout的拓展1:R-Dropout 3、Dropout的拓展2:Multi-Sample Dropout 4、Dropout的拓展3:DropConnect 5、Dropout的拓展4:Standout 6、Dropout的拓展5:Gaussian Dropout …

微信小程序开发:通过wx.login()获取用户唯一标识openid和unionid

下面代码展示了 openid 的获取过程。 想获取 unionid 需要满足条件:小程序已绑定到微信开放平台账号下,不然只会返回 openid。 【相关文档】 微信小程序开发:appid 和 secret 的获取方法 wx.login({success (res) {if (res.code) {// 发起网…

十二:枚举与注解

文章目录 01、枚举类的使用1.1、枚举类的理解1.2、自定义枚举类1.3、使用enum关键字定义枚举类1.4、Enum类中的常用方法1.5、使用enum关键字定义的枚举类实现接口 02、注解的使用2.1、注解的理解2.3、如何自定义注解2.4、jdk中4个基本的元注解的使用12.5、jdk中4个基本的元注解…

解锁创意灵感,探索FlutterExampleApps项目的奥秘

解锁创意灵感,探索FlutterExampleApps项目的奥秘 项目简介 FlutterExampleApps项目是一个包含各种示例应用链接的仓库,旨在演示Flutter应用开发中的各种功能、特性和集成。 项目包含了以下几个部分,每个部分都涵盖了不同的内容和主题&…

VO、DTO、DO、BO、PO

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 VO、DTO、DO、BO1.概念阿里Java开发手册分层领域模型: 2. VO 和 DTO 使用场景以下是一个使用VO和DTO的典型案例: 3.BO和DTO的区别 案例 VO、…

分享两个版本的数字孪生技术栈,都是AI回答的,较为精准

版本一: 数字孪生应用到的技术栈包括但不限于: 3D建模:数字孪生需要建立虚拟的三维模型,因此需要使用3D建模软件如AutoCAD、SketchUp、3ds Max等。 数据采集:数字孪生需要采集大量实时的物理数据,如传感…

为什么从没有负值的数据中绘制的小提琴图(Violin Plot)会出现负值部分?

🍉 CSDN 叶庭云:https://yetingyun.blog.csdn.net/ 小提琴图(Violin Plot) 是一种用于展示和比较数据分布的可视化工具。它结合了箱形图(Box Plot)和密度图(Kernel Density Plot)的特…

hive load data未正确读取到日期

1.源数据CSV文件日期字段值: 2.hive DDL语句: CREATE EXTERNAL TABLE test.textfile_table1(id int COMMENT ????, name string COMMENT ??, gender string COMMENT ??, birthday date COMMENT ????,.......) ROW FORMAT SERDE org.apache.…

QT中事件过滤器

Qt添加事件过滤器,设置拖放listWidget、TreeWidget、TableWidget控件。 #include "mainwindow.h" #include "ui_mainwindow.h"MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow) {ui->setupUi(this)…

UML---活动图

活动图概述 活动图(Activity Diagram)是UML(Unified Modeling Language,统一建模语言)中的一种行为建模工具,主要用于描述系统或业务流程中的一系列活动或操作。活动图通常用于描述用例中的行为&#xff0c…

SimpleDateFormat为什么是线程不安全的?

目录 在日常开发中,Date工具类使用频率相对较高,大家通常都会这样写:这很简单啊,有什么争议吗?格式化后出现的时间错乱。看看Java 8是如何解决时区问题的:在处理带时区的国际化时间问题,推荐使用…

[创业之路-88/管理者与领导者-128]:企业运行分层模型、研发管理全视野

目录 一、企业分层模型 1.1 愿景层 1.2 战略目标层 1.3 战术方法层 1.4 市场业务层 1.5 项目执行层 1.6 资源层 二、研发全视野、全流程 2.1 市场 2.2 战略规划 2.3 产品研发 2.3.1 概述 2.3.2 项目管理 2.3.3 研发业务管理(研发经理*N) – 管技术流程…

2024护眼大路灯哪个牌子好?6个挑选妙招助你选择优质落地灯!

如果大家平常关注大路灯,应该都会注意到一个情况——它确实大受众多用户的喜爱以及专业人士的认可,但是关于它的伤眼案例却从未减少。之所以如此矛盾,主要是因为市面上有太多的不专业大路灯,它们的选材用料以及品质非常糟糕&#…

Spring Boot 笔记 028 文章列表

1.1 导入中文语言包 1.2 显示文章分类 //回显文章分类 import { articleCategoryListService } from /api/article.js const articleCategoryList async () > {let result await articleCategoryListService();categorys.value result.data; }articleCategoryList() 1.3…

蓝牙BLE安全-SSP简单安全配对

SSP的配对过程由于可以根据设备的IO能力选择不同的关联模型,因此十分灵活,其提供了四种方式:Numeric Comparison、Passkey Entry、Just Works以及Out of Band (OOB) 。这里关联方式的选择实质上对后面的流程是有一定影响的,如Just…

Python实例|电商API接口数据采集的请求|爬取商品详情描述价格评论

近年来,随着互联网的发展,越来越多的数据以网页的形式存在于各个网站上。对于数据分析师、研究员或者仅仅是对数据感兴趣的人来说,如何高效地提取和分析网页数据成为了一项重要的技能。Python作为一门强大的编程语言,通过其丰富的…

【鸿蒙系统学习笔记】状态管理

一、介绍 资料来自官网:文档中心 在声明式UI编程框架中,UI是程序状态的运行结果,用户构建了一个UI模型,其中应用的运行时的状态是参数。当参数改变时,UI作为返回结果,也将进行对应的改变。这些运行时的状…

HTML的特殊字符

HTML的特殊字符 有些特殊的字符在 html 文件中是不能直接表示的&#xff0c;例如: 空格&#xff0c;小于号(<)&#xff0c;大于号(>)&#xff0c;按位与(&)。 空格 示例代码&#xff1a; 运行结果&#xff1a; 由于html 标签就是用 < > 表示的&#xff0…

原创个人java开源项目发布maven全球中央仓库详细过程示范和遇到的问题解决办法

文章目录 java项目上传到maven全球中央仓库&#xff08;原创个人开源项目发布maven中央仓库详细过程示范&#xff09;需求背景第一步 注册sonatype账号第二步 登录sonatype账号并申请新建项目第三步 准备个人GPG数字签名并发布到ubuntu第四步 准备maven配置第五步 修改项目配置…

java数据结构与算法刷题-----LeetCode155. 最小栈

java数据结构与算法刷题目录&#xff08;剑指Offer、LeetCode、ACM&#xff09;-----主目录-----持续更新(进不去说明我没写完)&#xff1a;https://blog.csdn.net/grd_java/article/details/123063846 1. 法一&#xff1a;使用辅助最小栈 解题思路&#xff1a;时间复杂度O(1)…