Python 中图外的图例 - matplotlib

2024-04-24

我试图在 matplotlib 中的绘图之外放置一个相当广泛的图例。图例有相当多的条目,每个条目可能很长(但我不知道具体有多长)。

显然,这很容易使用

legendHandle = plt.legend(loc = "center left", bbox_to_anchor = (1, 0.5))

但问题是图例被窗口边缘切断了。我花了很长时间寻找解决方案。到目前为止我能找到的最好的东西是:

box = ax.get_position()
ax.set_position([box.x0, box.y0, box.width * 0.8, box.height])
plt.legend(loc = "center left", bbox_to_anchor = (1, 0.5))

不幸的是,这并不能真正解决我的问题。由于对框宽度应用了明确的系数 0.8,因此这只适用于图形和图例宽度的一种特定组合。如果我调整图形窗口的大小,或者我的图例条目具有不同的长度,则它不起作用。

我只是不明白为什么将图例放在人物之外会如此困难。我习惯了 Matlab,它就这么简单

legend('Location', 'eastoutside')

Python 中是否有我缺少的类似内容?


经过多次尝试后,这是我能想到的最好的:

from matplotlib.lines import Line2D
from matplotlib.gridspec import GridSpec
from enum import Enum

class Location(Enum):
    EastOutside = 1
    WestOutside = 2
    NorthOutside = 3
    SouthOutside = 4

class Legend:
    def __init__(self, figure, plotAxes, location: Location):
        self.figure = figure
        self.plotAxes = plotAxes
        self.location = location

        # Create a separate subplot for the legend. Actual location doesn't matter - will be modified anyway.
        self.legendAxes = figure.add_subplot(1, 2, 1)
        self.legendAxes.clear() # remove old lines
        self.legendAxes.set_axis_off()

        # Add all lines from the plot to the legend subplot
        for line in plotAxes.get_lines():
            legendLine = Line2D([], [])
            legendLine.update_from(line)
            self.legendAxes.add_line(legendLine)

        if self.location == Location.EastOutside:
            self.legend = self.legendAxes.legend(loc = "center left")
        elif self.location == Location.WestOutside:
            self.legend = self.legendAxes.legend(loc = "center right")
        elif self.location == Location.NorthOutside:
            self.legend = self.legendAxes.legend(loc = "lower center")
        elif self.location == Location.SouthOutside:
            self.legend = self.legendAxes.legend(loc = "upper center")
        else:
            raise Exception("Unknown legend location.")

        self.UpdateSize()

        # Recalculate legend size if the size changes
        figure.canvas.mpl_connect('resize_event', lambda event: self.UpdateSize())

    def UpdateSize(self):
        self.figure.canvas.draw() # draw everything once in order to get correct legend size

        # Extract legend size in percentage of the figure width
        legendSize = self.legend.get_window_extent().inverse_transformed(self.figure.transFigure)
        legendWidth = legendSize.width
        legendHeight = legendSize.height

        # Update subplot such that it is only as large as the legend
        if self.location == Location.EastOutside:
            gridspec = GridSpec(1, 2, width_ratios = [1 - legendWidth, legendWidth])
            legendLocation = 1
            plotLocation = 0
        elif self.location == Location.WestOutside:
            gridspec = GridSpec(1, 2, width_ratios = [legendWidth, 1 - legendWidth])
            legendLocation = 0
            plotLocation = 1
        elif self.location == Location.NorthOutside:
            gridspec = GridSpec(2, 1, height_ratios = [legendHeight, 1 - legendHeight])
            legendLocation = 0
            plotLocation = 1
        elif self.location == Location.SouthOutside:
            gridspec = GridSpec(2, 1, height_ratios = [1 - legendHeight, legendHeight])
            legendLocation = 1
            plotLocation = 0
        else:
            raise Exception("Unknown legend location.")

        self.legendAxes.set_position(gridspec[legendLocation].get_position(self.figure))
        self.legendAxes.set_subplotspec(gridspec[legendLocation]) # to make figure.tight_layout() work if that's desired

        self.plotAxes.set_position(gridspec[plotLocation].get_position(self.figure))
        self.plotAxes.set_subplotspec(gridspec[plotLocation]) # to make figure.tight_layout() work if that's desired

这使得图例在我迄今为止测试过的情况下或多或少都正常。用法例如

import matplotlib.pyplot as plt

plt.ion()

figure = plt.figure()

plotAxes = figure.gca()

plotAxes.plot([1, 2, 3], [4, 5, 6], "b-", label = "Testaaaaaaaaaaaaaa 1")
plotAxes.plot([1, 2, 3], [6, 5, 4], "r-", label = "Test 2")

legend = Legend(figure, plotAxes, Location.EastOutside)

让我问我已经在评论中发布的问题...我将如何向 matplotlib 开发人员建议将此作为附加功能? (不是我的黑客,而是将图例置于图形之外的本地方式)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Python 中图外的图例 - matplotlib 的相关文章

  • 如何从字典构造defaultdict?

    如果我有d dict zip range 1 10 range 50 61 我怎样才能建立一个collections defaultdict出于dict 唯一的论点defaultdict似乎采取的是工厂功能 我必须初始化然后再经历原来的d并
  • 使用分组的多列熊猫绘制堆积条形图

    我有两个数据框 我需要获取它们之间的差异 然后在该差异之上绘制其中一个数据框 这是一个最小的例子 import pandas as pd import matplotlib pyplot as plt df1 pd DataFrame 2
  • chrome_options.binary_location() TypeError: 'str' 对象不可调用

    我希望每个人都好 我是 python 新手 我尝试运行这段代码 但我不明白问题是什么以及如何解决这个问题 我的代码是 from selenium import webdriver from time import sleep url raw
  • Pytorch“展开”等价于 Tensorflow [重复]

    这个问题在这里已经有答案了 假设我有大小为 50 50 的灰度图像 在本例中批量大小为 2 并且我使用 Pytorch Unfold 函数 如下所示 import numpy as np from torch import nn from
  • 将 unique_ptr 与 boost python 结合使用 - boost::shared_ptr 有效,但 unique_ptr 无效

    这可能与以下问题相同 Boost Python 没有 to python for std unique ptr https stackoverflow com questions 20590205 boost python no to py
  • 如何从numpy数组中获取两个最小值

    我想从数组中取出两个最小值x 但是当我使用np where A B np where x x min 0 1 我收到此错误 ValueError 需要超过 1 个值才能解压 我该如何修复这个错误 我需要在数组中按升序排列数字吗 您可以使用n
  • 如何在Python中打印出字母表中的第n个字母?

    ASCII 数学似乎在 Python 中不起作用 一 5 不起作用 如果没有字母数组 如何快速打印出字母表中的第 n 个字母 我天真的解决方案是这样的 letters A B C D E F G H I J K L M N O P Q R
  • 向 list.extend() 传递不可迭代对象

    我正在创建一个公共方法来允许调用者将值写入设备 例如将其称为 write vals 由于这些值将实时输入 因此我希望通过允许用户输入列表或单个值来简化用户的生活 具体取决于他们需要写入的值的数量 例如 write to device 1 2
  • Python 2to3 Windows CMD

    我已经安装了 python 32 包到 C python32 我还设置了路径 Python 路径 C Python32 Lib C Python32 DLLs C Python32 Lib lib tk 路径 C Python32 我想使用
  • 如何以编程方式关闭wx.DirDialog?

    我有 wxpython 应用程序 可以在单击按钮时打开 wx DirDialog dlg wx DirDialog self Choose a directory style wx DD DEFAULT STYLE if dlg ShowM
  • 使用多索引列对多列求和

    我有一个从数据透视表创建的数据框 看起来类似于 import pandas as pd d company1 False Negative April 2012 112 0 April 2013 370 0 April 2014 499 0
  • Python:从字符串访问变量[重复]

    这个问题在这里已经有答案了 这可能是非常基本和简单的事情 我可能只是在谷歌上搜索错误的术语 但希望这里有人可以帮助我 我仍然是编程的初学者 这从这个问题中可能是显而易见的 我正在寻找一种从字符串访问变量的方法 像这样 A1 B1 C1 my
  • 为什么 Python 的 argparse 对 SystemExit 使用错误代码 2?

    当我给 Python 的 argparse 输入它不喜欢的输入时 它会引发一个代码为 2 的 SystemExit 其中似乎意味着 没有这样的文件或目录 https docs python org 2 library errno html
  • 单个函数的 Numpy 均值和方差?

    使用 Numpy Python 是否可以从单个函数调用返回均值 AND 方差 我知道我可以单独做它们 但是计算样本标准差需要平均值 因此 如果我使用单独的函数来获取均值和方差 则会增加不必要的开销 我尝试在这里查看 numpy 文档 htt
  • 捕获 CommandOnCooldown 错误

    我正在制作一个有冷却时间的不和谐机器人 并且我正在尝试制作一个事件 当CommandOnCooldown发生错误时 机器人会通过私信告诉他们需要等待多长时间 这是我的代码 看起来一切正常 但它不知道 retry after 意味着什么 bo
  • 在 python 中将数组作为参数传递

    我是Python新手 现在我需要声明大小为 20 的数组并将该数组传递给函数 需要数组的函数如下 function args The args是一个输入function 谁能帮我 如何在 python 中传递数组 当你说 数组 时 我假设你
  • 是否可以使用 Google BERT 来计算两个文本文档之间的相似度?

    是否可以使用 Google BERT 来计算两个文本文档之间的相似度 据我了解 BERT 的输入应该是有限大小的句子 一些作品使用 BERT 来计算句子的相似度 例如 https github com AndriyMulyar semant
  • Python二进制数据读取

    urllib2 请求接收二进制响应 如下所示 00 00 00 01 00 04 41 4D 54 44 00 00 00 00 02 41 97 33 33 41 99 5C 29 41 90 3D 71 41 91 D7 0A 47 0
  • 将 sudo 与 Python 脚本结合使用

    我正在尝试编写一个小脚本来在每次执行脚本时安装 VirtualBox 共享文件夹 我想用Python 来做这件事 因为我正在尝试学习它来编写脚本 问题是我需要特权才能启动挂载命令 我可以将脚本作为 sudo 运行 但我更喜欢它自己创建 su
  • 无法比较类型“ndarray(dtype=int64)”和“str”

    Example of data that I want to replace 数据具有以下属性 购买 V 高 高 中 低 维持 V 高 高 中 低 门 2 3 4 5 更多 2 4人以上 lug boot 小 中 大 安全性低 中高 这就是

随机推荐

  • 将“onclick”应用于 iFrame 中的所有元素

    如何使用 JavaScript DOM 来应用onclick事件到链接内部iframe 这是我正在尝试但不起作用的方法 document getElementById myIframe contentDocument getElements
  • 使用 JOIN(大表性能)Postgresql 进行 UPDATE FROM?

    我试图让以下查询以合理的性能执行 UPDATE order item imprint SET item new id oi item new id FROM order item oi INNER JOIN order item impri
  • 通过 Rails 访问 has_many 上的附加值

    我在访问 has many 上名为 permission 的附加参数的值时遇到了真正的麻烦 这可能是很简单的事情 我的 3 个型号是 class User lt ActiveRecord Base has many players user
  • CultureAndRegionInfoBuilder 不存在

    好吧 这是一个奇怪的事情 我正在尝试使用以下方法创建自定义文化 using System Globalization var x new CultureAndRegionInfoBuilder 但我收到了令人讨厌的红色 Resharper
  • 在 Firebase 项目中集成 Gmail 连接

    我开发了一个应用程序 它使用 gmail api 来获取来自用户的所有邮件 然后我将此应用程序分为一个示例 几乎是空的 和一个执行所有操作的片段 这样我以后就可以轻松地将我的片段集成到我团队的项目设置中 现在我的片段位于另一个项目中 gma
  • 从 Lambda 向 AWS IoT Core 发布 MQTT 消息

    我是 AWS 世界的新手 目前正在开发一项 Alexa 技能 该技能只需向 AWS IoT Core 代理发布一条 mqtt 消息 与之前创建的 事物 和主题进行交互 目前我正在使用 boto3 但我不确定这是正确的路径 这是代码 但在部署
  • 移动 Safari - 视口设备高度未按预期工作

    我有一个网络应用程序 我试图在 iPad 3 上运行 当我拉起它时 该应用程序允许垂直滚动 但实际上不应该 我已经对其他网络应用程序执行了相同的过程 没有任何问题 并且不确定这次我错过了什么 在我的 html 的 head 元素内 我有以下
  • 如何使用 EditTextPreference 作为屏蔽密码文本字段?

    我有一个非常简单的问题 我有一个EditTextPreference我想用它来获取用户的密码 并且我希望它被屏蔽 我怎样才能做到这一点 下面是一个使用 xml 的简短示例
  • 对象切片,有优势吗?

    对象切片是指当子类被分配给基类时 对象失去一些属性或功能 就像是 Class A Class B extends A Class SomeClass A a new A B b new B Some where if might happe
  • 使用“in”关键字迭代 Javascript 数组

    貌似没明白这句话的意思inJavaScript 中的关键字 看看这个代码片段 http jsfiddle net 3LPZq http jsfiddle net 3LPZq var x 1 2 for i in x document wri
  • Onvif - 尝试了解它是如何工作的

    首先 我完全没有使用ONVIF的经验 我在一家公司获得了奖学金 并被要求与它一起工作 控制一些相机并从它们那里获取照片 但他们也不知道它是如何工作的 所以没有人可以帮助我很多 我正在阅读 ONVIF 网页上提供的规范 但我不太明白 我知道我
  • iOS 自定义标签栏

    我刚刚开始 iOS 开发 只是在玩 atm 我正在尝试将默认的选项卡栏按钮转换为更自定义的按钮 经过一番查看后 我发现您可以为每个按钮创建自定义状态 所以我这样做了 UIImage selectedImage0 UIImage imageN
  • 合并多个表

    我有很多表格描述了我的小公司的不同类型的支出和收益 并且我发现没有简单的方法来合并我的表格 就像我制作的这个例子一样 我希望在更新最后一个表时自动填充其他表的行 这样我就可以及时预见费用和收益 通过按日期升序自动排序绿色表 到目前为止 我发
  • python 中的结构体对象

    我想创建一个一次性的 结构 对象来保留各种状态标志 我的第一个方法是这样的 javascript风格 gt gt gt status object gt gt gt status foo 3 Traceback most recent ca
  • 如何在 Docker-Compose 中一起使用主机网络和任何其他用户定义的网络?

    我想将 Docker Compose 文件中定义的两个 Docker 容器相互连接 app and db 其中之一 app 也应该连接到host网络 容器应连接到通用的用户定义网络 appnet or default 使用嵌入式DNS来自
  • 如何在显示模态表时禁用 Cocoa 的默认动画?

    我想禁用 Cocoa 在显示模式表时执行的动画 Apple s 表编程指南 http developer apple com mac library documentation Cocoa Conceptual Sheets Concept
  • MySQL:什么是页面?

    在 MySQL 数据库的上下文中 我一辈子都不记得页面是什么 当我看到 8KB 页之类的内容时 这是否意味着每行 8KB 还是 数据库页是组织数据库文件中数据的内部基本结构 以下是有关 InnoDB 模型的一些信息 From 13 2 11
  • 使用 Apache Pig 的数据透视表

    我想知道是否可以在 Apache Pig 中一次性旋转一张表 Input Id Column1 Column2 Column3 1 Row11 Row12 Row13 2 Row21 Row22 Row23 Output Id Name V
  • 如何使 gradle processResources 任务更快

    我正在研究 Spring Boot 项目 并且我正在遭受构建时间的困扰 我的项目的 processResources 任务花费的时间太长 如果资源文件是最新的 大约只需要10秒 但如果文件至少更改一个 则需要几分钟的时间 这是因为一个资源库
  • Python 中图外的图例 - matplotlib

    我试图在 matplotlib 中的绘图之外放置一个相当广泛的图例 图例有相当多的条目 每个条目可能很长 但我不知道具体有多长 显然 这很容易使用 legendHandle plt legend loc center left bbox t