如何在 matplotlib 中对图例句柄进行分组?
How to group legend handles in matplotlib?
我想知道如何在 matplotlib
中制作出如此奇特的图例。特别是,我想知道如何分组,例如,并排对应于 $\tau=10$ 的蓝色实线和虚线,或者所有虚线(或实线)在一起,如传说。
图片来自this arxiv paper.
多亏了对我原来的 post 的评论,我可以想出一个进行分组的脚本,尽管如前所述,但并不像我想的那么直接。该脚本本质上是 SO 上其他答案的改编版本。
import matplotlib.pyplot as plt
from matplotlib.path import Path
from matplotlib import patches as mpatches
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
codes = [Path.MOVETO, Path.LINETO]
# the following lines unfortunately may not be refactored
verts1 = [(x0, y0+0.25*height),(x0 + width, y0+0.25*height)]
verts2 = [(x0, y0+0.75*height),(x0 + width, y0+0.75*height)]
path1 = Path(verts1,codes)
path2 = Path(verts2,codes)
patch1 = mpatches.PathPatch(path1)
patch2 = mpatches.PathPatch(path2,ls='--',)
patch = PatchCollection([patch1,patch2],match_original=True)
handlebox.add_artist(patch)
return patch
fig, ax = plt.subplots()
ax.legend([AnyObject()], ['My grouped handlers'],
handler_map={AnyObject: AnyObjectHandler()})
同时导致
Take-home 条消息
图例文档指定了一种使用 HandlerTuple
(示例 here)对条目进行分组的更自然的方式。但是由于 mpl
水平放置标记,这种方法与我希望的正交:)。如果您不介意,请先选择该选项。
据我了解,自定义图例的设计使其不会与您要绘制的数据交换任何信息。例如,在我的例子中,我无法告诉 AnyObjectHandler
有多少行将被分组,它们是什么 linestyle
,等等。这是一个很好的通用性决定,代价是 (最小)对代码重构的危害。
我想知道如何在 matplotlib
中制作出如此奇特的图例。特别是,我想知道如何分组,例如,并排对应于 $\tau=10$ 的蓝色实线和虚线,或者所有虚线(或实线)在一起,如传说。
图片来自this arxiv paper.
多亏了对我原来的 post 的评论,我可以想出一个进行分组的脚本,尽管如前所述,但并不像我想的那么直接。该脚本本质上是 SO 上其他答案的改编版本。
import matplotlib.pyplot as plt
from matplotlib.path import Path
from matplotlib import patches as mpatches
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
codes = [Path.MOVETO, Path.LINETO]
# the following lines unfortunately may not be refactored
verts1 = [(x0, y0+0.25*height),(x0 + width, y0+0.25*height)]
verts2 = [(x0, y0+0.75*height),(x0 + width, y0+0.75*height)]
path1 = Path(verts1,codes)
path2 = Path(verts2,codes)
patch1 = mpatches.PathPatch(path1)
patch2 = mpatches.PathPatch(path2,ls='--',)
patch = PatchCollection([patch1,patch2],match_original=True)
handlebox.add_artist(patch)
return patch
fig, ax = plt.subplots()
ax.legend([AnyObject()], ['My grouped handlers'],
handler_map={AnyObject: AnyObjectHandler()})
同时导致
Take-home 条消息
图例文档指定了一种使用
HandlerTuple
(示例 here)对条目进行分组的更自然的方式。但是由于mpl
水平放置标记,这种方法与我希望的正交:)。如果您不介意,请先选择该选项。据我了解,自定义图例的设计使其不会与您要绘制的数据交换任何信息。例如,在我的例子中,我无法告诉
AnyObjectHandler
有多少行将被分组,它们是什么linestyle
,等等。这是一个很好的通用性决定,代价是 (最小)对代码重构的危害。