简体   繁体   English

Matplotlib PatchCollection到图例

[英]Matplotlib PatchCollection to Legend

Currently, I am trying to make my own custom legend handler by creating a proxy artist (?) patch using PatchCollections and then following http://matplotlib.org/users/legend_guide.html to make a custom handler. 目前,我正在尝试通过使用PatchCollections创建代理艺术家(?)补丁程序来制作自己的自定义图例处理程序,然后按照http://matplotlib.org/users/legend_guide.html创建自定义处理程序。

However I am running into a roadblock in trying to implement this into the legend. 但是,在尝试将其实现到图例中时遇到了障碍。 The arguments for legend takes in patches, but not patchcollections. 图例的参数包含补丁,但不包含patchcollection。

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.mlab as mlab
import matplotlib.patches as mpatches
from matplotlib.path import Path
from matplotlib.collections import PatchCollection

fig = plt.figure()
ax = fig.add_subplot(111)

verts1 = [(0.,0.),(0.,1.),(1.,1.),(0.51,0.51),(0.,0.),(0.,0.),]
codes1 = [Path.MOVETO,Path.LINETO,Path.LINETO,Path.LINETO,Path.MOVETO,Path.CLOSEPOLY,]
path1 = Path(verts1,codes1)
patch1 = mpatches.PathPatch(path1,ls='dashed',ec='red',facecolor="none")


verts2 = [(0.49,0.49),(0.,0.),(1.,0.),(1.,1.),(0.5,0.5),(0.,0.),]
codes2 = [Path.MOVETO,Path.LINETO,Path.LINETO,Path.LINETO,Path.MOVETO,Path.CLOSEPOLY,]
path2 = Path(verts2,codes2)
patch2 = mpatches.PathPatch(path2,ls='solid',edgecolor='red', facecolor="none")

patch = PatchCollection([patch1,patch2],match_original=True)

ax.set_xlim(-2,2)
ax.set_ylim(-2,2)

ax.add_collection(patch)

视觉效果

The above is the code to visualise the handler. 上面是可视化处理程序的代码。 Basically a rectangle with the upper triangle as dashed lines and the lower as solid 基本上是一个矩形,其中上三角为虚线,下三角为实线

Using, 使用,

plt.legend([patch],["hellocello"],loc='upper right')

Recreates the error. 重新创建错误。 Is there a workaround? 有解决方法吗?

From the example in this section , it looks like you need to define an object and express all coordinates in terms of the handlebox size, 在本的示例中,您似乎需要定义一个对象并根据车把的大小来表达所有坐标,

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.mlab as mlab
import matplotlib.patches as mpatches
from matplotlib.path import Path
from matplotlib.collections import PatchCollection

class AnyObject(object):
    pass

class AnyObjectHandler(object):
    def legend_artist(self, legend, orig_handle, fontsize, handlebox):
        x0, y0 = handlebox.xdescent, handlebox.ydescent
        width, height = handlebox.width, handlebox.height
        hw = 0.5*width; hh = 0.5*height
        verts1 = [(x0,y0),(x0,y0+height),(x0+width,y0+height),((x0+hw)*1.01,(y0+hh)*1.01),(x0,y0),(x0,y0),]
        codes1 = [Path.MOVETO,Path.LINETO,Path.LINETO,Path.LINETO,Path.MOVETO,Path.CLOSEPOLY,]
        path1 = Path(verts1,codes1)
        patch1 = mpatches.PathPatch(path1,ls='dashed',ec='red',facecolor="none")

        verts2 = [((x0+hw)*0.99,(y0+hh)*0.99),(x0,y0),(x0+width,y0),(x0+width,y0+height),(x0+hw,y0+hh),(x0,y0),]
        codes2 = [Path.MOVETO,Path.LINETO,Path.LINETO,Path.LINETO,Path.MOVETO,Path.CLOSEPOLY,]
        path2 = Path(verts2,codes2)
        patch2 = mpatches.PathPatch(path2,ls='solid',edgecolor='red', facecolor="none")

        patch = PatchCollection([patch1,patch2],match_original=True)

        handlebox.add_artist(patch)
        return patch


fig = plt.figure()
ax = fig.add_subplot(111)

ax.set_xlim(-2,2)
ax.set_ylim(-2,2)

plt.legend([AnyObject()], ['hellocello'],
           handler_map={AnyObject: AnyObjectHandler()})

plt.show()

This seems to work okay with PatchCollection , at least for me on matplotlib version 1.4.3. 至少对我来说,在matplotlib版本1.4.3上,这与PatchCollection似乎可以正常工作。 The result looks like, 结果看起来像

在此处输入图片说明

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM