使用自定义处理程序时忽略matplotlib图例参数

使用自定义处理程序时忽略matplotlib图例参数,matplotlib,legend,Matplotlib,Legend,我试图画一个自定义的图例,在一条线上,我有一些半径越来越大的圆,后面是“收入”这个词。我认为这是一个很好的方法来说明一个圆的大小对应于受试者的收入。 图例必须手动绘制。我是如何做到这一点的: class AnyObjectHandler(HandlerBase): def create_artists(self, legend, orig_handle, x0, y0, width, height, fontsize, trans):

我试图画一个自定义的图例,在一条线上,我有一些半径越来越大的圆,后面是“收入”这个词。我认为这是一个很好的方法来说明一个圆的大小对应于受试者的收入。 图例必须手动绘制。我是如何做到这一点的:

class AnyObjectHandler(HandlerBase):
    def create_artists(self, legend, orig_handle,
                       x0, y0, width, height, fontsize, trans):

        legend.numpoints = 1
        l1 = plt.Line2D([x0 - 40, y0 + width], [0.3 * height, 0.3 * height], color='blue',
                        marker='o', markersize=10, markerfacecolor="blue")

        return [l1]

fig.legend([object], ['Income'], numpoints=1,
           handler_map={object: AnyObjectHandler()})
问题是,即使我尝试两次指定
numpoints==1
,图例仍然带有默认的每行2个标记。一个相关的问题(我发现如何将
numpoints
设置为1)是:

这是上述代码产生的结果:


与此相反,我希望线条只显示一个圆。不管是哪个圆。

您可以在处理程序的
create\u artist
方法中创建第二个
Line2D
。这允许线条使用
Line2D
,标记使用另一个

import matplotlib.pyplot as plt
from matplotlib.legend_handler import HandlerBase

class AnyObjectHandler(HandlerBase):
    def create_artists(self, legend, orig_handle,
                       x0, y0, width, height, fontsize, trans):

        l1 = plt.Line2D([x0 - 40, x0 + width], [0.3 * height, 0.3 * height], 
                        color='blue', marker='None')

        m1 = plt.Line2D([x0 - 40], [0.3 * height], color='blue', linestyle="",
                        marker='o', markersize=10, markerfacecolor="blue")

        return [l1, m1]


fig, ax = plt.subplots()

fig.legend([object], ['Income'],
           handler_map={object: AnyObjectHandler()})

plt.show()

此解决方案独立于
numpoints
参数,并且在您已经知道始终只需要一个点的情况下可能非常有用

或者,您可以访问
numpoints
以指定要使用的点数。这最好通过对实际了解
numpoints
参数的处理程序进行子类化来实现

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.legend_handler import HandlerNpoints

class AnyObjectHandler(HandlerNpoints):
    def create_artists(self, legend, orig_handle,
                       x0, y0, width, height, fontsize, trans):

        l1 = plt.Line2D([x0 - 40, x0 + width], [0.3 * height, 0.3 * height], 
                        color='blue', marker='None')

        num = self.get_numpoints(legend)
        if num == 1:
            xdata = [x0 - 40]
        else:
            xdata = np.linspace(x0 - 40, x0 + width, num)
        m1 = plt.Line2D(xdata, [0.3 * height]*len(xdata), color='blue', 
                        linestyle="", marker='o', markersize=10)

        return [l1, m1]


fig, ax = plt.subplots()

fig.legend([object], ['Income'], numpoints=1,
           handler_map={object: AnyObjectHandler()})

plt.show()
对于
numpoints=1
这将给出与上面相同的结果,但是您可以指定
numpoints=2

numpoints=3


等等。

1)如果您在
Line2D
s中的任何地方都不使用
numpoints
,他们怎么知道您希望它使用它?2) 创建一条包含2个点的线。这两个点中哪一个应该有标记?
Line2D
不接受任何与点有关的参数。它只是一行点,它们的数量通常由
图例的
numpoints
参数控制。只要图例不是自定义的,这就适用于我。请检查我的编辑上的链接问题。Line2D应允许使用
markevery
。或者,您可以手动创建点。在任何一种情况下,您都有责任在创建的代码中实际使用numpoints somoehere。如果你能告诉我,根据
numpoints
,图例应该是什么样子,我当然可以提供一个解决方案。我添加了一个我得到的图像和我想要实现的解释。为了简化,我们只考虑一条线。要复制,只需创建一个随机图,并使用此代码创建图例,因为图例与基础图形完全无关。