代码之家  ›  专栏  ›  技术社区  ›  arash

如何在matplotlib中创建这样一个奇特的传说?

  •  0
  • arash  · 技术社区  · 4 年前

    我想知道我怎样才能在 matplotlib 。特别是,我想知道如何分组,例如,与$\tau=10$并排对应的实线和蓝色虚线,或图例下部的所有虚线(或实线)一起分组。

    enter image description here

    图像取自 this arxiv paper

    0 回复  |  直到 4 年前
        1
  •  1
  •   arash    4 年前

    多亏了我原来帖子上的评论,我可以想出一个脚本来进行分组,尽管如上所述,但并不像我想的那么直截了当。剧本本质上是另一个答案的改编版本。

    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()})
    

    而导致

    enter image description here


    带回家的消息

    1. 图例文档指定了一种更自然的方式,使用 HandlerTuple (示例 here ).但是自从 mpl 水平放置标记,这种方法与我所希望的正交:)。如果你不介意的话,那就先选择这个选项。

    2. 据我所知,自定义图例的设计使它们不会与要绘制的数据交换任何信息。例如,在我的情况下,我不能告诉 AnyObjectHandler 要分组多少行,它们的 linestyle 这是一个很好的通用性决策,代价是对代码重构造成(最小)伤害。

    推荐文章